fix(deploy): puxa a imagem publicada em vez da que está em cache

Um deploy recriava os contentores mas continuava a correr o código
antigo. "latest" é uma tag móvel, e o Docker considera satisfeita
qualquer tag que já tenha localmente: o compose pedia
protocols:latest, o host já tinha uma imagem com esse nome, e a que o
Release acabara de publicar nunca era descarregada. O deploy terminava
com sucesso, os contentores reiniciavam saudáveis, e nada do que
estava a correr mudava.

Foi assim que várias correções que passaram no CI nunca chegaram ao
site: a rota /api/v1/mail/delete respondia 404 em produção enquanto
existia no código e nos testes, e a pasta Reports existia na base de
dados - a migração corre a partir da imagem certa - sem existir em
nenhuma das interfaces.

pull_policy: always nos seis serviços que consomem imagens
publicadas. Os que usam imagens de terceiros com versão fixa
(postgres:16-alpine, redis:7-alpine, clamav) ficam como estão: aí a
tag identifica um conteúdo imutável e voltar a puxar não acrescenta
nada.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Lucas RayanandClaude Opus 5 committed 2026-08-22 10:35:53 -03:00
1 parent 203316f2c3
commit ac0521cb9b
1 file changed
+30
+30
View File
@@ -61,6 +61,11 @@ services:
# unhealthy exactly when it has done its job. # unhealthy exactly when it has done its job.
migrate: migrate:
image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/migrations:${IMAGE_TAG:-latest} image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/migrations:${IMAGE_TAG:-latest}
# "latest" is a moving tag and Docker considers a tag it already holds
# locally to be satisfied, so recreating this container silently reused
# the cached image and the newly published one was never fetched: the
# deploy reported success while the running code stayed put.
pull_policy: always
restart: "no" restart: "no"
logging: *default-logging logging: *default-logging
depends_on: depends_on:
@@ -76,6 +81,11 @@ services:
# ------------------------------------------------------------ RSPAMD # ------------------------------------------------------------ RSPAMD
rspamd: rspamd:
image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/rspamd:${IMAGE_TAG:-latest} image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/rspamd:${IMAGE_TAG:-latest}
# "latest" is a moving tag and Docker considers a tag it already holds
# locally to be satisfied, so recreating this container silently reused
# the cached image and the newly published one was never fetched: the
# deploy reported success while the running code stayed put.
pull_policy: always
restart: *restart restart: *restart
logging: *default-logging logging: *default-logging
environment: environment:
@@ -131,6 +141,11 @@ services:
# -------------------------------------------------------------- AUTH # -------------------------------------------------------------- AUTH
auth: auth:
image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/auth:${IMAGE_TAG:-latest} image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/auth:${IMAGE_TAG:-latest}
# "latest" is a moving tag and Docker considers a tag it already holds
# locally to be satisfied, so recreating this container silently reused
# the cached image and the newly published one was never fetched: the
# deploy reported success while the running code stayed put.
pull_policy: always
restart: *restart restart: *restart
logging: *default-logging logging: *default-logging
environment: environment:
@@ -164,6 +179,11 @@ services:
# ----------------------------------------------------------- STORAGE # ----------------------------------------------------------- STORAGE
storage: storage:
image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/storage:${IMAGE_TAG:-latest} image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/storage:${IMAGE_TAG:-latest}
# "latest" is a moving tag and Docker considers a tag it already holds
# locally to be satisfied, so recreating this container silently reused
# the cached image and the newly published one was never fetched: the
# deploy reported success while the running code stayed put.
pull_policy: always
restart: *restart restart: *restart
logging: *default-logging logging: *default-logging
environment: environment:
@@ -195,6 +215,11 @@ services:
# --------------------------------------------------------- PROTOCOLS # --------------------------------------------------------- PROTOCOLS
protocols: protocols:
image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/protocols:${IMAGE_TAG:-latest} image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/protocols:${IMAGE_TAG:-latest}
# "latest" is a moving tag and Docker considers a tag it already holds
# locally to be satisfied, so recreating this container silently reused
# the cached image and the newly published one was never fetched: the
# deploy reported success while the running code stayed put.
pull_policy: always
restart: *restart restart: *restart
logging: *default-logging logging: *default-logging
ports: ports:
@@ -273,6 +298,11 @@ services:
# -------------------------------------------------------------- WEB # -------------------------------------------------------------- WEB
web: web:
image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/webmail:${IMAGE_TAG:-latest} image: ${IMAGE_NAMESPACE:-ghcr.io/lucasrguerra/lambdamail}/webmail:${IMAGE_TAG:-latest}
# "latest" is a moving tag and Docker considers a tag it already holds
# locally to be satisfied, so recreating this container silently reused
# the cached image and the newly published one was never fetched: the
# deploy reported success while the running code stayed put.
pull_policy: always
restart: *restart restart: *restart
logging: *default-logging logging: *default-logging
environment: environment: