110 lines
3.4 KiB
YAML
110 lines
3.4 KiB
YAML
# Template Canônico — Stack Docker Swarm (Octal)
|
|
|
|
## Uso
|
|
```bash
|
|
# 1. Copiar template
|
|
cp runbooks/swarm-stack-template.yml runbooks/<NOME_STACK>.yml
|
|
|
|
# 2. Editar: services, imagens, réplicas, labels Caddy
|
|
vim runbooks/<NOME_STACK>.yml
|
|
|
|
# 3. Deploy via Docker CLI (Swarm nativo — recomendado)
|
|
docker stack deploy -c runbooks/<NOME_STACK>.yml <NOME_STACK>
|
|
|
|
# 4. Aplicar labels Caddy via Docker CLI (obrigatório — Swarm não herda do compose)
|
|
docker service update \
|
|
--label-add 'caddy=<DOMINIO>' \
|
|
--label-add 'caddy.reverse_proxy={{upstreams <PORTA>}}' \
|
|
<NOME_STACK>_<SERVICE>
|
|
```
|
|
|
|
## ⚠️ Rede `public` — Attachable=false
|
|
|
|
| Método | Funciona? | Motivo |
|
|
|--------|-----------|--------|
|
|
| `docker stack deploy` (CLI) | ✅ SIM | Daemon Docker local ignora a restrição |
|
|
| Portainer API (`POST /api/stacks`) | ❌ NÃO | Docker Remote API respeita `Attachable=false` |
|
|
|
|
**Decisão**: Usar `docker stack deploy` CLI para todas as stacks.
|
|
Stacks criadas por CLI aparecem no `docker stack ls` e no Swarm, mas
|
|
NÃO aparecem como gerenciáveis no Portainer UI.
|
|
|
|
Para ter controle total pelo Portainer, a rede `public` precisaria ser recriada com
|
|
`--attachable`, o que causaria uma breve interrupção nos containers existentes.
|
|
Atualmente não vale a pena — 19 containers em produção usam `public`.
|
|
|
|
---
|
|
|
|
## Template Completo (v3.9)
|
|
|
|
```yaml
|
|
version: '3.9'
|
|
|
|
networks:
|
|
public:
|
|
external: true # overlay swarm — Attachable=false (modelo atual)
|
|
|
|
services:
|
|
<service-name>:
|
|
image: <IMAGEM>:<TAG>
|
|
networks:
|
|
- public
|
|
deploy:
|
|
replicas: 1
|
|
endpoint_mode: dnsrr # DNS round-robin — necessário para reverse proxy
|
|
update_config: # zero-downtime deploy
|
|
parallelism: 1
|
|
delay: 10s
|
|
rollback_config: # rollback automático se falhar
|
|
parallelism: 1
|
|
delay: 10s
|
|
restart_policy:
|
|
condition: on-failure
|
|
max_attempts: 3
|
|
```
|
|
|
|
---
|
|
|
|
## Regras Obrigatórias
|
|
|
|
### 1. Rede `public`
|
|
- É a **única rede overlay** do cluster Octal
|
|
- Criada uma única vez: `docker network create --driver overlay --attachable public`
|
|
- `Attachable: false` no modelo atual — não alterar sem planejamento
|
|
- Nunca declarar `external: false` em services — quebra Swarm
|
|
|
|
### 2. Nomes de serviço
|
|
- **SEM prefixo** no compose: Swarm injeta `<stack>_` automaticamente
|
|
- Ex: `games-demo` no compose → `project_games-demo` no Swarm ✓
|
|
- Ex: `project_games-demo` no compose → `project_project_games-demo` ✗ (duplicado)
|
|
|
|
### 3. Labels Caddy
|
|
- **NÃO funcionam pelo compose** — `deploy.labels` não vira `Config.Labels`
|
|
- Aplicar **obrigatoriamente** via CLI após deploy:
|
|
`docker service update --label-add 'caddy=<DOMINIO>' <STACK>_<SERVICE>`
|
|
|
|
### 4. Labels Traefik (fallback opcional)
|
|
- Funcionam pelo compose via `deploy.labels`:
|
|
```yaml
|
|
deploy:
|
|
labels:
|
|
- traefik.enable=true
|
|
- traefik.http.routers.<NOME>.rule=Host(`<DOMINIO>`)
|
|
```
|
|
|
|
---
|
|
|
|
## Stacks Existentes (referência)
|
|
|
|
| Stack | Criada por | Controlável Portainer? |
|
|
|-------|------------|----------------------|
|
|
| `git` | Portainer API | ✅ SIM |
|
|
| `bot` | Portainer API | ✅ SIM |
|
|
| `pro` | Portainer API | ✅ SIM |
|
|
| `design` | Portainer API | ✅ SIM |
|
|
| `proxy` | Portainer API | ✅ SIM |
|
|
| `project` | `docker stack deploy` CLI | ⚠️ NÃO (Attachable=false) |
|
|
| `dock` | Portainer API | ✅ SIM |
|
|
| `code` | Portainer API | ✅ SIM |
|
|
| `database` | Portainer API | ✅ SIM |
|