pull_policy del agente: nunca :latest en un up de prod
Resumen
Cómo no bajar una imagen distinta a las 3am: pull_policy never o missing, digest pin, distinto de rebuild. Docker Compose pull_policy, 3 de septiembre de 2026. latest se pulla incluso con missing. up no es el canal de updates del bot.

Qué resuelve
Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.
compose up -d con image: node:22 puede pull y cambiar el runtime. El bot de anoche no es el de hoy. pull_policy: never (prod) o missing (laptop). Distinto de pin digest: el pin dice cuál; pull_policy dice cuándo. Fuentes oficiales consultadas el 3 de septiembre de 2026.
La regla
pull_policy: never
en prod. El CI hace docker pull del digest y compose up. Un restart de VPS no toca registry.
always es para Preview si quieres fresco. No en el VPS del webhook.
Relación con el pin
Digest @sha256:… + never: si la imagen no está, up falla. Bien. Mejor fail que silent latest.
build: local + pull_policy en image: mezclado: documenta una fuente. multistage produce el tag que el CI pushea.
Tabla

| Entorno | Policy | Por qué |
|---|---|---|
| prod VPS | never | no sorpresas |
| CI | missing / explicit pull | cache ok |
| laptop | missing | primer clone |
| preview | always o CI rebuild | fresco |
Errores comunes

| Síntoma | Causa | Fix |
|---|---|---|
| Node distinto post-reboot | always/default | never + digest |
| up falla missing image | never sin load | CI pull antes |
| :latest en yaml | hábito | pin |
| Fly auto-pull | no Compose | image ref en toml |
compose pull en cron | “updates” | pipeline con digest |
Relación con el resto
- Digest: pin imagen.
- CI: Actions.
- Preview: preview vs prod.
- dockerignore no sustituye pull_policy.
Checklist
- prod
pull_policy: never - imagen por digest
- CI pull + up
- no cron
compose pull - Ensayo: sin red,
upusa local - rollback = tag anterior ya en disco o load
FAQ
¿Workers? Bundles, no pull de Compose.
¿Railway? Buildpack/image de deploy, no este yaml.
¿build: . en prod? Entonces no hay pull de app; sí de FROM. Pin el FROM.
El ensayo: desconecta red. compose up -d ok. Con always, falla o no debería usarse.
if_not_present es alias de missing. build policy rebuilda. No rebuildes prod en el VPS.
Qué no hacer
No pongas always “para parches de seguridad”. Los parches van por digest en CI, con rollback. Un pull nocturno no es parche; es ruleta.
No mezcles image: ghcr.io/org/agent:main mutable + never. Never congela lo que haya hoy en disco, que puede ser un main de hace 3 semanas o de hace 3 minutos. Digest.
compose pull en un cron del VPS bypasses CI. Quítalo.
Techos oficiales (curl 2026-09-03)
Compose pull_policy (hoy) decide cuándo Compose tira del registry al arrancar:
| Valor | Qué hace |
|---|---|
always | pull siempre |
never | no pull; usa cache de la plataforma; falla si no hay imagen |
missing | pull solo si no está en cache. Default si no usas Compose Build Specification |
if_not_present | alias de missing (compat) |
build | construye; rebuild si ya está |
daily | consulta registry si el último pull fue hace más de 24 h |
weekly | igual, más de 7 días |
every_<duration> | umbral libre: w / d / h / m / s o combo. Ejemplo oficial: every_12h |
Trampa documentada en la misma página: el tag latest se pulla siempre, incluso con missing. missing no te salva un image: node:latest. Prod = digest + never.
image (hoy): formato OCI [registry/][project/]nombre más tag o @digest. Ejemplos oficiales incluyen redis@sha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398bc4b991aac7. Si la imagen no existe en la plataforma, Compose intenta pull según pull_policy. Sin image y sin spec de build, Compose no arranca.
docker image pull (hoy): NAME con tag o digest. Alias docker pull. Sin tag, Engine usa :latest. Concurrent downloads del daemon: 3 capas a la vez; bájalo con --max-concurrent-downloads si el VPS timeout-ea. Flags: -a/--all-tags, --platform (API 1.32+), -q. El ejemplo oficial de debian el 3 de septiembre de 2026 resolvió Digest: sha256:3f1d6c17773a45c97bd8f158d665c9709d7b29ed7917ac934086ad96f92e4510 — ese sha cambia; no lo copies como pin eterno, cópialo el día del deploy.
Rollback
El digest anterior debe existir local o en registry. never no baja el viejo solo. El job de rollback hace pull del sha viejo o load del artifact. rollback.
El ensayo extra: compose config muestra never. up con registry down = ok.
daily / weekly / every_12h no son un canal de parches. Son “¿hace cuánto no miro el tag mutable?”. En un bot 24/7 eso es un deploy no revisado. El CI publica un digest; el VPS no mira el reloj.
Postgres y pull
El servicio postgres:16 también se mueve si always. Pin postgres por digest o mayor. Un upgrade de minor en un up = surprise WAL. depends_on healthy no detecta “otra imagen”.
Caddy igual. Tres imágenes, tres policies.
secrets no viajan en el pull; viven en el host. Un pull never no rota tokens. Bien.
Watchtower / similar: apágalo. Es always con marketing.
Auth al registry: el VPS no necesita pull si never + imagen ya cargada (docker load o pull en deploy). Menos credenciales en el host.
Cómo verificar:
docker compose config | grep -A1 pull_policy
docker image ls --digests
# sin red: compose up -d no debe hablar con el registry
Siguiente paso: si never y igual cambia el binario, el tag no está pinneado → digest. Sin runtime: curso.
Lecturas relacionadas
Sigue explorando Deploy y otras piezas para builders.



