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).
npm run dev:runner # = infisical run … -- docker compose up --builddocker compose up --build # o mesmo, sem InfisicalO 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.
Como as credenciais entram no container
Seção intitulada “Como as credenciais entram no container”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:
# 1. cofre → shell → pass-throughRUNNER_CONNECTORS=real DD_API_KEY=… GITHUB_TOKEN=… npm run dev:runner# 2. arquivo (fallback offline)cp runner.secrets.env.example runner.secrets.env# preencha, e o env_file carregadocker compose up --buildSem nenhum dos dois, o runner fica em synthetic: dados falsos, sem credencial.
Os volumes, e o que cada um resolve
Seção intitulada “Os volumes, e o que cada um resolve”volumes: - ./dev-certs:/certs:ro - ${AWS_CONFIG_DIR:-${HOME}/.aws}:/root/.aws:rodev-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.
restart: unless-stopped
Seção intitulada “restart: unless-stopped”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.
Por que o control-plane não está neste Compose
Seção intitulada “Por que o control-plane não está neste Compose”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.