Docker Swarm
Deploy em produção com stack, Traefik e segredos.
Em produção a recomendação é Docker Swarm (ou Portainer em cima do Swarm), com a imagem:
automacaodebaixocusto/omnilink-api:latestO arquivo de referência no produto é um docker-stack.yml (Compose 3.8). Swarm não usa depends_on.
Pré-requisitos
- Swarm inicializado no manager.
- Rede overlay externa para o Traefik (criar antes do deploy):
docker network create --driver overlay network_public- Traefik já rodando nessa rede, com entrypoint
websecuree certresolverletsencryptresolver(labels do stack assumem isso). - Segredos reais gerados (placeholders do stack falham com
APP_ENV=production).
Gerar segredos
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
python3 -c "import secrets; print(secrets.token_urlsafe(32))"
python3 -c "import secrets; print(secrets.token_urlsafe(32))"| Linha | Variável | Regra |
|---|---|---|
| 1 | ENCRYPTION_KEY | 44 caracteres Fernet |
| 2 | WEBHOOK_SIGNING_SECRET | ≥ 16; não pode ser change-me |
| 3 | METRICS_TOKEN | ≥ 16 |
Copie os mesmos valores em api e worker. A senha do Postgres em POSTGRES_PASSWORD deve coincidir com a senha em DATABASE_URL.
O stack oficial hoje usa só environment: — não há docker secret implementado. Em ambiente corporativo você pode migrar para secrets; a API só lê variáveis de ambiente.
Serviços da stack
| Serviço | Imagem | Réplicas | Redes | Volume |
|---|---|---|---|---|
| API | automacaodebaixocusto/omnilink-api:latest | 1 | internal + network_public | — |
| Worker | mesma imagem | 1 | só internal | — |
| Postgres | postgres:16 | 1 | só internal | omnilink_pgdata_v2 |
| Redis | redis:7 | 1 | só internal | nenhum no stack |
- A API não publica porta no host; o Traefik encaminha para a porta
8000. - Healthcheck da API:
GET http://127.0.0.1:8000/health/ready(interval 30s, start_period 40s). - Redis no stack: sem senha.
- Ajuste o host Traefik (ex.:
Host(\omnilink.seudominio.com`)`).
Réplicas de worker acima de 1 não estão no stack oficial — se aumentar, monitore CPU/RAM do Playwright. Em produção costuma-se --concurrency=1 no Celery.
Deploy
Com o docker-stack.yml preenchido (segredos e domínio):
docker stack deploy -c docker-stack.yml omnilinkConferir:
docker stack services omnilinkLogs:
docker service logs -f omnilink_api_omnilink
docker service logs -f omnilink_worker_omnilinkAtualizar (mesmo comando, nova tag/config):
docker stack deploy -c docker-stack.yml omnilinkRemover:
docker stack rm omnilinkO que tratar como segredo
| Valor | Onde | Por quê |
|---|---|---|
ENCRYPTION_KEY | api + worker | Fernet do cofre |
WEBHOOK_SIGNING_SECRET | api + worker | HMAC X-Omnilink-Signature |
METRICS_TOKEN | api + worker | /metrics e /health/diagnostics |
| Senha Postgres | postgres + DATABASE_URL | Deve ser a mesma |
x-api-key dos tenants | não é env | Header HTTP; hash no banco |
Tabela completa: Variáveis de ambiente.
Dependências
| Dependência | Versão no stack | Na mesma stack? |
|---|---|---|
| PostgreSQL | postgres:16 | Sim (ou externo via DATABASE_URL) |
| Redis | redis:7 | Sim (Celery + /health/ready) |
| Playwright/Chromium | Já na imagem | Não |
| Traefik | Fora deste stack | Só a API na network_public |
Postgres e Redis no Swarm ficam só na overlay internal — não exponha na internet.