feat: auto-update app-dono-cliente when a new image is pushed to :latest

Adds a StepRunUpdater step that starts app-dono-updater after the app
container comes up: a poll loop (docker pull, compare image IDs,
recreate on change) baked into the official docker:cli image via
`sh -c`, reusing the same docker run argv as the initial container
start so the two can't drift.

Not built on Watchtower: containrrr/watchtower was archived upstream
in Dec 2025 with no maintained successor recommended for production
use, so this avoids taking on that dependency.
This commit is contained in:
2026-08-26 12:30:44 -03:00
parent ef126eaf61
commit a05b98fdf5
8 changed files with 244 additions and 18 deletions
+24 -8
View File
@@ -45,7 +45,9 @@ O instalador conduz o operador por um assistente (wizard) no terminal que:
5. Coleta, via formulários, as configurações de **aplicação, servidor, banco de dados
e certificados**.
6. **Gera o `config.toml`** e sobe o container `app-dono-cliente`.
7. Exibe a confirmação de sucesso.
7. Sobe o container **`app-dono-updater`**, que mantém o `app-dono-cliente`
atualizado automaticamente a cada novo push em `:latest`.
8. Exibe a confirmação de sucesso.
## Pré-requisitos
@@ -131,6 +133,11 @@ go run ./cmd
┌──────────────────┐
│ Sobe container │ (app-dono-cliente)
│ app-dono-cliente │
└────────┬─────────┘
▼
┌──────────────────┐
│ Sobe container │ (app-dono-updater,
│ de auto-update │ atualiza o app-cliente sozinho)
└────────┬─────────┘
▼
✅ Concluído
@@ -161,20 +168,29 @@ o instalador (no caso do `config.toml`).
## Containers e rede Docker
Todos os containers são conectados à rede Docker **`app-dono_app`** (criada
automaticamente se não existir).
`app-dono-cliente` e `vproxy` são conectados à rede Docker **`app-dono_app`** (criada
automaticamente se não existir). O `app-dono-updater` fica fora dessa rede — ele só fala
com o daemon Docker via socket, não com os outros containers pela rede.
| Container | Imagem | Quando sobe |
| ------------------ | ------------------------------------------------- | -------------------- |
| `app-dono-cliente` | `hub.davinti.com.br:443/app-dono/app-cliente` | Sempre |
| `vproxy` | `hub.davinti.com.br:443/davinti-vproxy` | Quando não há IP púb.|
| Container | Imagem | Quando sobe |
| --------------------- | ------------------------------------------------ | -------------------- |
| `app-dono-cliente` | `hub.davinti.com.br:443/app-dono/app-cliente` | Sempre |
| `vproxy` | `hub.davinti.com.br:443/davinti-vproxy` | Quando não há IP púb.|
| `app-dono-updater` | `docker:cli` | Sempre |
Características:
- Ambos sobem com `--restart unless-stopped`.
- Todos sobem com `--restart unless-stopped`.
- O container do app expõe a porta configurada no host, mapeando para a `8080` interna,
e monta o `config.toml` e o diretório de certificados como volumes.
- O `vproxy` roda com `--cap-add=NET_ADMIN` e acesso a `/dev/net/tun`.
- O `app-dono-updater` **não** é o Watchtower — esse projeto foi arquivado pelos
mantenedores originais em dez/2025 sem um sucessor mantido recomendado para produção.
Em vez disso, é um loop simples (`sh -c`) rodando na imagem oficial `docker:cli`: a
cada 5 minutos baixa a imagem do `app-dono-cliente`, compara com a que está rodando e,
se mudou, recria o container. Usa as mesmas credenciais do login feito no passo 2 (via
`~/.docker/config.json`) e precisa de acesso ao socket do Docker
(`/var/run/docker.sock`) para poder recriar o container.
- O **modo compatibilidade** (`seccomp=unconfined`) pode ser ativado para máquinas
antigas onde o seccomp padrão causa problemas.