Pular para o conteúdo

Docker Compose

O Compose é o único caminho de deploy que este repositório entrega pronto. São dois arquivos: docker-compose.yml (desenvolvimento, contra um control-plane seu) e docker-compose.fleet.yml (sobreposição para produção).

Terminal window
npm run dev:runner # = infisical run … -- docker compose up --build
docker compose up --build # o mesmo, sem Infisical

O script dev:runner embrulha o Compose no Infisical porque é o cofre que este time usa. Se você não usa Infisical, o segundo comando funciona igual: as credenciais só precisam chegar por um dos dois caminhos abaixo.

O Compose usa uma lista em environment:, não um mapa, justamente para misturar valor fixo (NOME=valor) com pass-through (NOME puro, sem =). Pass-through significa: pega do shell do host, e se não existir no host, a chave é omitida no container, e não vira string vazia.

Há dois caminhos, nessa ordem de preferência:

Terminal window
# 1. cofre → shell → pass-through
RUNNER_CONNECTORS=real DD_API_KEY= GITHUB_TOKEN= npm run dev:runner
Terminal window
# 2. arquivo (fallback offline)
cp runner.secrets.env.example runner.secrets.env
# preencha, e o env_file carrega
docker compose up --build

Sem nenhum dos dois, o runner fica em synthetic: dados falsos, sem credencial.

volumes:
- ./dev-certs:/certs:ro
- ${AWS_CONFIG_DIR:-${HOME}/.aws}:/root/.aws:ro

dev-certs/: os PEMs de desenvolvimento gerados por npm run dev:certs. O docker-entrypoint.sh os lê de /certs e os exporta como RUNNER_CERT_PEM, RUNNER_KEY_PEM e RUNNER_CA_PEM, porque o runner lê PEM inline, não caminho, o que evita o pesadelo de PEM multilinha em env_file.

~/.aws: é o par obrigatório de RUNNER_AWS_CRED_MODE=chain. Sem esse volume, o container não enxerga o cache que o aws sso login escreve, e a cadeia de credenciais falha sem dizer que é isso, o clássico “funciona no meu terminal e não no container”. Quando o token de SSO expirar, rode aws sso login no host: o container passa a ler o cache renovado sem reiniciar nada.

extra_hosts:
- "host.docker.internal:host-gateway"

No Linux isso mapeia host.docker.internal para o host; no Docker Desktop já resolve e a linha é no-op. É o que faz RUNNER_TUNNEL_URL=wss://host.docker.internal:8443 alcançar um control-plane rodando na sua máquina.

Em desenvolvimento o runner se reergue sozinho. Isso é intencional e casa com o ciclo 1006 → exited 0 → restart que você vê quando o túnel do outro lado reinicia: o exited 0 é o timer de reconexão ser unref’d, e o restart o traz de volta quando o túnel volta.

Em produção esse comportamento é invertido de propósito. Veja Deploy em produção.

Ele consome os @rootpilot/* por link de arquivo para o repositório edge irmão, que fica fora de qualquer contexto de build do Docker. Containerizá-lo está bloqueado por um interim de projeto. O arranjo de desenvolvimento é: control-plane no host, runner no container.