← Blog

Fazendo deploy de Phoenix quando sua fila de jobs já está dentro da release

Railyard

14 de outubro de 2026 · 2 min de leitura

A maioria dos frameworks precisa de um segundo processo pra implantação só pra rodar jobs em segundo plano — um dyno worker, um container separado, algo pra manter em sincronia com o build da aplicação web. O Phoenix geralmente não precisa, porque o Oban roda como parte da mesma árvore de supervisão OTP que o próprio endpoint web: o executor de jobs não é uma segunda aplicação, ele já está vivo no instante em que o web inicializa.

O que é lido do mix.exs

  • Bancos de dados são detectados a partir das dependências, não declarados duas vezes: ecto_sql/postgrex provisiona o Postgres, ecto_ch/ch provisiona o ClickHouse, redix provisiona o Redis.
  • SECRET_KEY_BASE é gerado uma vez, não deixado pra você produzir e guardar você mesmo.
  • MIX_ENV=prod e PHX_SERVER=true são definidos automaticamente — as duas flags de ambiente que uma release compilada do Phoenix de fato precisa pra servir tráfego em vez de ficar ociosa.
railyard create my-app https://github.com/me/my-app --addons postgres

ou a mesma URL Git pelo dashboard depois que o GitHub estiver conectado.

A parte que é genuinamente diferente sobre releases compiladas

Uma release compilada de Elixir não tem mix em tempo de execução — o comando de migration que funciona no desenvolvimento (mix ecto.migrate) não existe no artefato que de fato vai pro ar. O Railyard encontra onde a release coloca seu próprio migrator e roda isso no lugar (bin/migrate se a release definir um, senão bin/<app> eval), e mix phx.server se torna bin/<app> start do mesmo jeito. Essa distinção — comando de desenvolvimento versus o que a release compilada de fato expõe — é a coisa mais comum que trava um primeiro deploy de Elixir em qualquer plataforma, e ela é tratada antes da primeira migration rodar.

Se um node worker dedicado realmente vale a pena

O Oban não precisa de um segundo processo pra maioria das aplicações — mas se o volume de jobs é alto o suficiente pra que uma fila lenta comece a sufocar requisições web, separar ele pro próprio node ainda é uma adição de uma linha, não uma mudança de arquitetura:

web:    bin/my_app start
worker: bin/my_app eval "MyApp.Release.worker()"
railyard scale my-app worker=2

Mesma release, mesmo build, iniciado de forma diferente — adicione ou edite isso na aba Workers sem nenhuma mudança no repositório.

Configuração e secrets

Tudo que o config/runtime.exs lê com System.get_env/2 — BASE_URL, HTTP_PORT, LISTEN_IP, DATABASE_URL, CLICKHOUSE_DATABASE_URL e qualquer outra coisa — é uma variável simples em Variables, ou definida via railyard env:set my-app KEY=VALUE, nunca embutida na release compilada. A mesma release roda sem mudanças do staging até a produção.

Referência completa: Phoenix and Elixir docs, Workers and scheduled jobs.

Suba uma aplicação Phoenix agora mesmo.

O mix.exs é lido automaticamente — ecto.migrate, SECRET_KEY_BASE e o banco de dados já ficam todos conectados.

Plano grátis, sem cartão, e 14 dias de Pro para cada equipe nova. Um preço fixo por equipe.