Fazendo deploy de um serviço Go: o build que não precisa de runtime
Um build Go produz um único binário vinculado estaticamente, sem nada pra resolver em tempo de execução — nenhuma versão de interpretador pra fixar, nenhuma gem ou pacote pra buscar no servidor que está pra rodar a aplicação. Isso é uma coisa genuinamente diferente de construir comparado à maioria das aplicações em linguagens interpretadas, e isso se reflete em menos lugares pra um deploy dar errado: uma vez que o binário compila, ele roda, ponto final.
O que é detectado
- O próprio Go é detectado a partir do
go.mod— incluindo um módulo que vive numa subpasta (server/go.modao lado de um diretóriofrontend/), encontrado e construído a partir do lugar certo automaticamente. - Um import de driver de banco de dados conhecido —
github.com/jackc/pgx,github.com/lib/pq,github.com/go-sql-driver/mysql,github.com/redis/go-redis— provisiona o banco correspondente e injetaDATABASE_URLouREDIS_URL, sem addon pra adicionar à mão antes. - O build roda pelo Railpack por padrão, ou pelo seu próprio Dockerfile se o repositório tiver um.
railyard create my-app https://github.com/me/my-app --port 8080
ou a mesma URL pelo dashboard depois que o GitHub estiver conectado. A única exigência que vale deixar clara: o binário precisa escutar na $PORT, e em todas as interfaces, não só em localhost.
Workers, já que o Go não tem convenção de framework pra detectar
Diferente do Rails ou do Django, o Go não tem uma biblioteca de fila de jobs dominante pra procurar — não há nada pra oferecer automaticamente como worker. Isso tudo bem, porque é uma linha de qualquer jeito:
web: ./server
worker: ./server -mode=worker
As duas linhas rodam exatamente o mesmo binário construído; a main() lê uma flag ou variável de ambiente pra decidir qual loop de fato rodar. Um build, vários tipos de processo, cada um escalado independentemente:
railyard scale my-app worker=2
Pra qualquer coisa que roda numa agenda em vez de continuamente, o Cron roda o binário com uma flag diferente no horário agendado e mantém um histórico de execução — um modelo mais limpo do que um loop for { time.Sleep(...) } embutido no processo worker.
Configuração e secrets
Tudo lido com os.Getenv é uma variável de ambiente simples em Variables, ou definida com railyard env:set my-app KEY=VALUE — nunca compilada no binário, então o exato mesmo artefato de build roda sem mudanças do staging até a produção. Sem recompilar por ambiente, que é o ponto principal: uma diferença de configuração entre staging e produção deveria ser uma variável, nunca um build diferente.
Construindo sua própria imagem, quando você quiser
railyard deploy my-app --local constrói com seu próprio Docker e envia uma única imagem diretamente, em vez de usar o builder compartilhado da equipe — útil quando um build precisa de algo específico do seu toolchain local que o caminho de build padrão não precisa saber.
Referência completa: Go docs, Workers and scheduled jobs.