Docker Compose
Compose é o caminho mais direto para rodar o Agent num host único (uma VM dedicada, por exemplo). Para orquestradores, veja Kubernetes ou a configuração de produção.
Um compose.yml mínimo
Seção intitulada “Um compose.yml mínimo”services: whystack-agent: image: <endereço>/whystack-agent@sha256:<digest> restart: unless-stopped stop_grace_period: 150s volumes: - whystack-identity:/identity environment: RUNNER_TUNNEL_URL: wss://tunnel.whystack.ai:8443 RUNNER_ENROLL_URL: https://app.whystack.ai RUNNER_ATTESTATION_MODE: bootstrap-token RUNNER_BOOTSTRAP_TOKEN: ${RUNNER_BOOTSTRAP_TOKEN} RUNNER_IDENTITY_DIR: /identity RUNNER_INSTANCE_ID: agent-prod-1 RUNNER_CONNECTORS: real RUNNER_SECRET_STORE_MODE: aws NODE_ENV: production
volumes: whystack-identity:stop_grace_period maior que RUNNER_DRAIN_TIMEOUT_MS (2 minutos por padrão): senão o
SIGKILL chega no meio da drenagem.
Saúde do contêiner
Seção intitulada “Saúde do contêiner”A imagem declara um HEALTHCHECK de liveness (whystack-health live), sem porta nenhuma: o Agent
grava o sinal em arquivo e o Docker o lê por exec. O docker compose ps mostra healthy quando o
processo está vivo, o que não quer dizer conectado. Para saber se ele está servindo:
docker compose exec whystack-agent whystack-health readySe você subir o contêiner com read_only: true, monte tmpfs: [/tmp]: é onde o sinal é gravado
(RUNNER_HEALTH_DIR).
A identidade precisa de um volume gravável
Seção intitulada “A identidade precisa de um volume gravável”É o que faz docker compose pull && up -d não custar um bootstrap token novo. Sem ele, a identidade
morre com o container e o token anterior já foi gasto: ele é de uso único.
Prefira um volume nomeado, como no exemplo acima. A imagem já traz /identity pertencendo ao uid
1000 (ela roda como não-root), e um volume nomeado herda essa posse ao ser criado, ou seja,
funciona sem você fazer nada.
Um bind mount (./identity:/identity) não herda nada: ali a posse é a do diretório no host, e ele
precisa ser do uid 1000. Nunca monte com :ro.
Se o diretório não for gravável, o boot não falha. O Agent avisa e segue, e você só descobre no deploy seguinte:
could not persist identity — next boot will re-enroll from scratchOs certificados, se você usa certificado provisionado
Seção intitulada “Os certificados, se você usa certificado provisionado”volumes: - ./certs:/certs:roO diretório deve conter runner.crt, runner.key e ca.pem. O entrypoint os lê e exporta como
RUNNER_CERT_PEM, RUNNER_KEY_PEM e RUNNER_CA_PEM. O Agent lê PEM inline, não caminho, e
montar o diretório evita o pesadelo de PEM multilinha dentro de env_file.
Esse caminho ignora enrollment e identidade persistida: os dois blocos acima deixam de valer, e o certificado não se renova. Ver Identidade e enrollment.
Se o Agent roda em EC2 e usa a cadeia de credenciais
Seção intitulada “Se o Agent roda em EC2 e usa a cadeia de credenciais”Com RUNNER_AWS_CRED_MODE=chain, a cadeia padrão do SDK resolve pelo instance profile sem nenhum
volume extra. Se em vez disso você usa um perfil local por arquivo, monte-o:
volumes: - ${HOME}/.aws:/home/node/.aws:roSem esse volume o container não enxerga o perfil, e a cadeia falha sem dizer que é isso: o clássico “funciona no meu terminal e não no container”.