[{"data":1,"prerenderedAt":169},["ShallowReactive",2],{"seo-verification":3,"blog-docker-compose-actualizacion-buenas-practicas-vps-ma-es":6,"promo-bar-likely":168},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-docker-compose-actualizacion-buenas-practicas-vps-ma-es",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"noindex":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":27,"featuredImage":29,"bgImage":30,"posterImage":31,"relatedSolution":29,"intro":32,"sections":33,"ctaTitle":109,"ctaBody":110,"ctaButton":111,"ctaUrl":112,"relatedPosts":113},427,"docker-compose-actualizacion-buenas-practicas-vps",{"fr":12,"en":13,"ar":14,"es":10},"docker-compose-mise-a-jour-best-practices-vps","docker-compose-update-best-practices-vps","أفضل-ممارسات-تحديث-docker-compose-على-vps","Actualizar un stack Docker Compose en producción","Protocolo para actualizar Docker Compose en producción sin pérdida de datos: version pinning, backup de volúmenes y rollback en dos minutos.",10,6,false,"2026-10-09T00:00:00+00:00","2026-11-08T01:13:13+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},3,"Despliegue","deploiement","bg-success\u002F10 text-success",[28],{"id":23,"name":24,"slug":25,"color":26,"icon":25},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fdocker-compose-mise-a-jour-best-practices-vps-poster.svg","Un `docker compose pull` seguido de `up -d` siempre funcionó — hasta el día en que dejó de funcionar. Las rupturas de compatibilidad de Meilisearch, Supabase (PostgreSQL 15→17) y Langfuse (v3→v4) lo recuerdan: una instancia estable, en producción desde hace meses, puede negarse a arrancar o rechazar sus datos entrantes tras una actualización sin preparación. Esta guía te da un protocolo reproducible: haz un backup antes de hacer pull, revisa las notas de versión antes de relanzar y vuelve a la imagen anterior en menos de dos minutos si algo falla.",[34,38,46,49,68,72,75,103,106],{"type":35,"title":36,"body":37},"h2","Por qué `latest` es el verdadero culpable","Cuando una imagen Docker etiquetada como `latest` se actualiza en el registry, tu `docker compose pull` la descarga en silencio. Sin advertencia, sin diff. Reinicias el stack y descubres que el nuevo contenedor no puede leer los datos que dejó el anterior.\n\nEs exactamente el riesgo con **Meilisearch**. La base de datos lleva el número de versión del motor que la escribió: al subir de versión, el nuevo motor se niega a abrirla mientras no se le pida explícitamente migrarla con `--upgrade-db` (o la variable `MEILI_UPGRADE_DB`). Con una política de reinicio, el contenedor entra entonces en crash-loop. Y una vez migrada la base, la imagen anterior ya no puede abrirla: Meilisearch no admite la vuelta atrás. La única red de seguridad limpia es un dump o un snapshot del volumen creado antes de la actualización — imposible una vez migrada la base o bloqueado el contenedor.\n\nEl tag `latest` no resuelve a la misma imagen según el momento del pull. Dos desarrolladores que ejecutan `docker compose pull` con doce horas de diferencia pueden descargar versiones distintas. En un stack de producción, esta ambigüedad es inaceptable. La solución no es evitar las actualizaciones: es **controlar explícitamente qué versión está en ejecución** y decidir conscientemente cuándo pasar a la siguiente.",{"type":39,"title":40,"items":41},"ul","Qué cubre esta guía — y qué no",[42,43,44,45],"**Qué cubre esta guía**: el protocolo paso a paso para actualizar un stack Docker Compose en un VPS — version pinning, backup de volúmenes, revisión de notas de versión, rollback rápido, healthchecks como red de seguridad.","**Cubierto en otras guías**: el checklist de hardening inicial (`docker-compose-production-checklist`), la configuración de `depends_on` y `service_healthy` (`docker-compose-depends-on-healthcheck`), y la comparativa de herramientas de actualización automática como Watchtower o Diun.","**Lo que esta guía no recomienda**: Watchtower o cualquier herramienta de auto-pull en producción — ese es precisamente el antipatrón que ilustran los casos de breaking changes.","**Público objetivo**: desarrolladores y agencias que gestionan uno o más stacks Docker Compose en producción en un VPS, con acceso root y volúmenes persistentes.",{"type":35,"title":47,"body":48},"Paso 1 — Fija todas tus imágenes","La primera acción, antes de cualquier actualización, es reemplazar cada `image: getmeili\u002Fmeilisearch:latest` o `image: supabase\u002Fpostgres` por una versión explícita.\n\nDos formas son aceptables:\n\n- **Tag de versión**: `image: getmeili\u002Fmeilisearch:v1.53.0` — legible, versionable en git, fácil de parchear.\n- **Digest SHA256**: `image: getmeili\u002Fmeilisearch@sha256:abc123…` — inmutable, garantiza que descargas exactamente el mismo artefacto en cada redespliegue, incluso si el tag fue sobreescrito.\n\nPara obtener el digest de una imagen ya en ejecución:\n\n```bash\ndocker inspect --format='{{index .RepoDigests 0}}' getmeili\u002Fmeilisearch:v1.53.0\n```\n\nUna vez fijadas tus imágenes, haz commit del `docker-compose.yml` en git. Cada bump de versión se convierte en un commit, lo que te da un historial claro y un rollback trivial (`git revert` + `docker compose up -d`).",{"type":50,"title":51,"steps":52},"steps","Protocolo de actualización — los 5 pasos",[53,56,59,62,65],{"title":54,"body":55},"Lee las notas de versión antes de hacer pull","Primero, consulta las notas de versión de la nueva versión. Busca las palabras `breaking`, `migration`, `incompatible`, `pg_upgrade`, `dump`. Esto no es opcional: Supabase documentó explícitamente que actualizar de PostgreSQL 15 a 17 **requiere un `pg_upgrade` manual** — el contenedor PG 17 se niega a arrancar sobre un volumen PG 15, y el proceso de inicialización no migra los datos automáticamente.\n\nPara Langfuse v4 (v4.0.0 publicada el 29 de julio de 2026), los SDKs Python v2 y anteriores son **rechazados en la ingesta** por el nuevo stack — un cambio disruptivo que afecta a todos los servicios cliente que rastrean mediante la API antigua.\n\nTres minutos de lectura te ahorran varias horas de recuperación de datos.",{"title":57,"body":58},"Haz backup de los volúmenes antes del pull","Nunca hagas pull sin tener un backup utilizable. Para volúmenes nombrados, dos enfoques:\n\n**Dump aplicativo (recomendado para bases de datos)** — el servicio debe estar `healthy` antes de hacer el dump:\n\n```bash\ndocker compose exec -T db pg_dump -U postgres -Fc mydb > backup_$(date +%Y%m%d_%H%M%S).dump\n```\n\nLa opción `-T` desactiva el pseudoterminal: sin ella, el flujo binario del dump puede alterarse.\n\n**Snapshot de volumen en crudo** — útil para almacenes binarios (Meilisearch, Redis, MinIO):\n\n```bash\ndocker run --rm \\\n  --volumes-from $(docker compose ps -q meilisearch) \\\n  -v $(pwd)\u002Fbackups:\u002Fbackup \\\n  alpine tar czf \u002Fbackup\u002Fmeili_$(date +%Y%m%d_%H%M%S).tar.gz \u002Fmeili_data\n```\n\nVerifica que el backup es legible antes de continuar. Un archivo de dump corrupto descubierto durante la recuperación es el escenario más costoso que existe.",{"title":60,"body":61},"Descarga la nueva imagen y pruébala fuera de producción","Actualiza el tag en tu `docker-compose.yml`, luego descarga la imagen sin reiniciar el servicio:\n\n```bash\ndocker compose pull meilisearch\n```\n\nSi tu entorno lo permite, prueba la nueva imagen sobre un clon del volumen en un entorno ddev o una VM de staging antes de tocar producción. Revisa los logs de arranque en busca de errores de migración:\n\n```bash\ndocker compose up -d meilisearch\ndocker compose logs -f meilisearch\n```\n\nEspera a que el healthcheck alcance el estado `healthy` antes de validar. Un servicio que arranca pero no está `healthy` todavía no es un servicio listo.",{"title":63,"body":64},"Verifica los healthchecks","Un healthcheck bien configurado es tu primera línea de detección. Debe estar presente en cada servicio crítico del stack, en formato Compose v2:\n\n```bash\nhealthcheck:\n  test: [\"CMD-SHELL\", \"curl -sf http:\u002F\u002Flocalhost:7700\u002Fhealth || exit 1\"]\n  interval: 10s\n  timeout: 5s\n  retries: 5\n  start_period: 30s\n```\n\nEl campo `start_period` es crítico para servicios de arranque lento (bases de datos, motores de búsqueda): evita que Docker declare el contenedor `unhealthy` durante la fase de inicialización y desencadene un reinicio prematuro.\n\nConsulta `docker-compose-depends-on-healthcheck` para la configuración completa de `service_healthy` en PostgreSQL — el mismo principio aplica a cualquier servicio que necesite un período de calentamiento.",{"title":66,"body":67},"Rollback si algo falla","Si la nueva versión no arranca o produce errores, el rollback debe tomar menos de dos minutos. El procedimiento:\n\n1. Vuelve al tag anterior en `docker-compose.yml` (o `git revert` si hiciste commit del bump).\n2. Reinicia únicamente el servicio afectado, sin recrear los volúmenes:\n\n```bash\ndocker compose up -d --no-deps --force-recreate meilisearch\n```\n\n3. Revisa los logs inmediatamente:\n\n```bash\ndocker compose logs -f meilisearch\n```\n\nEl flag `--no-deps` es esencial: reinicia el servicio objetivo sin tocar los otros contenedores (base de datos, caché, proxy). Sin él, `docker compose up -d` puede recrear todo el stack.\n\n⚠️ Si la nueva versión migró el formato de los datos en disco (Meilisearch tras `--upgrade-db`, Supabase PG17), revertir la imagen no es suficiente — por eso el backup del volumen es una precondición, no una opción.",{"type":69,"title":70,"body":71},"tip","Mantén la versión anterior disponible localmente","Antes de descargar la nueva imagen, etiqueta la imagen actualmente en producción con un nombre de retención:\n\n```bash\ndocker tag getmeili\u002Fmeilisearch:v1.53.0 getmeili\u002Fmeilisearch:rollback\n```\n\nEsto te permite volver al estado exacto de producción en caso de emergencia, incluso sin acceso al registry o con conexión lenta. En un VPS con ancho de banda limitado, este tag local te ahorra varios minutos de descarga en el peor momento.",{"type":35,"title":73,"body":74},"Los breaking changes recientes que derribaron instancias","Estos cuatro ejemplos ilustran por qué el protocolo anterior no es teórico.\n\n**Meilisearch** (al subir de versión): un motor más reciente se niega a abrir una base escrita por una versión anterior, con `Your database version (…) is incompatible with your current engine version`, mientras no se pase `--upgrade-db`. Esa migración puede cambiar el formato en disco: en la v1.37.0 (marzo de 2026), los índices vectoriales aún en formato arroy se convirtieron al nuevo almacén HNSW (hannoy). Y la vuelta atrás no está soportada (`Downgrade is not supported`). La única salida limpia tras un fallo es haber exportado un dump antes de la actualización y luego importarlo (`meilisearch --db-path \u002Fmeili_data --import-dump \u002Fbackup.dump`) — algo posible solo si exportaste antes de actualizar.\n\n**Supabase Docker PostgreSQL 15 → 17** (PG 17 por defecto desde el 17 de junio de 2026): el contenedor `supabase\u002Fpostgres:17` no puede leer un volumen inicializado por PG 15. Supabase documenta explícitamente que el salto requiere un `pg_upgrade` mediante un script dedicado — el proceso de inicialización del contenedor no lo hace automáticamente. Sin una migración previa, la base de datos no arranca.\n\n**Langfuse v3 → v4** (v4.0.0 publicada el 29 de julio de 2026): la v4 abandona los endpoints de ingesta batch legacy en favor de OpenTelemetry. Los SDKs Python v2 y anteriores y los SDKs JS\u002FTS v3 y anteriores son **rechazados en la ingesta** en cuanto el stack v4 funciona en su modo de escritura por defecto (`events_only`); los modos `legacy` y `dual` permiten escalonar la migración. Si tus servicios cliente no han migrado antes de la actualización del servidor, pierden silenciosamente todos sus trazados.\n\n**NocoDB (serie 2026.09)**: ninguna base rota, pero sí un cambio incompatible anunciado con antelación. Las notas de la 2026.09.0 recuerdan que las fechas devueltas por la API REST, los webhooks y las exportaciones pasarán de la precisión de segundo a la de milisegundo en PostgreSQL y SQLite en una próxima versión. Un cliente que lea las fechas con un formato estricto fallará sin que el servidor avise de nada — justo lo que la lectura de las notas de versión permite anticipar. Otra trampa, independiente de la versión: una instalación con bind-mounts (`.\u002Fpostgres`, `.\u002Fnocodb`) cuya ruta de montaje cambia entre dos despliegues arranca sobre una base vacía. Los volúmenes nombrados evitan esta deriva.",{"type":76,"title":77,"headers":78,"rows":83},"comparison","Estrategias de actualización: comparativa",[79,80,81,82],"Estrategia","Seguridad de datos","Tiempo de preparación","Rollback",[84,89,94,99],[85,86,87,88],"`docker compose pull` + `up -d` directo","Sin garantía — breaking changes no detectados","\u003C 1 minuto","Difícil si los datos fueron migrados",[90,91,92,93],"Bump de tag versionado + backup de volumen","Alta — datos guardados antes de cualquier cambio","10 a 20 minutos","Trivial: revertir tag + `up -d --no-deps`",[95,96,97,98],"Test en staging antes de prod","Máxima — breaking changes detectados fuera de prod","Variable según el entorno","No necesario si el test pasó",[100,101,102,102],"Imagen fijada por digest SHA256","Alta — inmune al tag-overwrite","Igual que tag versionado",{"type":35,"title":104,"body":105},"Integrar este protocolo en tu flujo de trabajo","Un protocolo que queda en una guía no sirve de nada. Para aplicarlo sistemáticamente, externaliza la versión en un archivo `.env` versionado en git:\n\n```bash\n# .env\nMEILISEARCH_VERSION=v1.53.0\nPOSTGRES_VERSION=15.6\n```\n\n```bash\n# docker-compose.yml\nservices:\n  meilisearch:\n    image: getmeili\u002Fmeilisearch:${MEILISEARCH_VERSION}\n```\n\nActualizar una versión se convierte entonces en un único commit sobre `.env` — legible en `git log`, reversible con `git revert`, y desplegable por CI\u002FCD sin modificar el archivo Compose principal.\n\nPara agencias que gestionan múltiples stacks de clientes, crea un archivo `CHANGELOG_INFRA.md` por cliente: cada actualización queda registrada con la versión anterior, la fecha, el backup realizado y el resultado. Esto también te protege contractualmente ante un eventual incidente posterior.",{"type":69,"title":107,"body":108},"Automatizar sin perder el control","Si quieres ser notificado de nuevas versiones sin auto-pull, **Diun** (Docker Image Update Notifier) monitoriza tu registry y te envía una notificación (Slack, email, webhook) cuando hay una nueva imagen disponible. Tú decides cuándo actualizar.\n\nEsta es la diferencia fundamental con Watchtower: Diun notifica, Watchtower actúa. En un stack de producción con volúmenes persistentes, la notificación es el nivel correcto de automatización — la acción sigue siendo manual y precedida del protocolo anterior.","Un VPS con acceso root para aplicar este protocolo","Dumps completos, snapshots antes de actualizar, rollback a una imagen anterior: este protocolo requiere acceso root y almacenamiento local controlable. El hosting compartido no te da este nivel de control sobre los volúmenes Docker.","Ver los VPS Cloud","\u002Fvps-cloud",[114,131,148],{"id":115,"slug":116,"slugs":117,"title":121,"excerpt":122,"readTime":123,"views":124,"isPinned":19,"noindex":19,"publishedAt":125,"updatedAt":126,"category":127,"categories":128,"featuredImage":29,"bgImage":30,"posterImage":130,"relatedSolution":29},229,"checklist-docker-compose-en-produccion",{"fr":118,"en":119,"ar":120,"es":116},"docker-compose-production-checklist","docker-compose-in-production-10-point-checklist","docker-compose-في-الإنتاج-قائمة-التحقق-من-10-نقاط","Docker Compose en producción: checklist de 10 puntos","Docker Compose en producción: 10 ajustes, health checks, secretos, rollback, solución de errores y paso de docker-compose v1 a docker compose en Ubuntu 26.04.",12,1,"2026-08-06T00:00:00+00:00","2026-10-23T13:27:09+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},[129],{"id":23,"name":24,"slug":25,"color":26,"icon":25},"\u002Fblog\u002Fcovers\u002Fdocker-compose-production-checklist-poster.svg",{"id":132,"slug":133,"slugs":134,"title":138,"excerpt":139,"readTime":140,"views":141,"isPinned":19,"noindex":19,"publishedAt":142,"updatedAt":143,"category":144,"categories":145,"featuredImage":29,"bgImage":30,"posterImage":147,"relatedSolution":29},282,"docker-compose-healthcheck-postgresql",{"fr":135,"en":136,"ar":137,"es":133},"docker-compose-depends-on-healthcheck","depends-on-is-not-enough-postgresql-healthcheck-in-compose","depends-on-لا-يكفي-healthcheck-لـ-postgresql-في-compose","depends_on no basta: healthcheck de PostgreSQL en Compose","Por qué `depends_on` por sí solo no garantiza que PostgreSQL esté listo, y cómo configurar un healthcheck fiable con `service_healthy` para evitar las race conditions.",8,0,"2026-08-19T00:00:00+00:00","2026-09-07T11:26:10+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},[146],{"id":23,"name":24,"slug":25,"color":26,"icon":25},"\u002Fblog\u002Fcovers\u002Fdocker-compose-depends-on-healthcheck-poster.svg",{"id":149,"slug":150,"slugs":151,"title":155,"excerpt":156,"readTime":17,"views":157,"isPinned":19,"noindex":19,"publishedAt":158,"updatedAt":159,"category":160,"categories":165,"featuredImage":29,"bgImage":30,"posterImage":167,"relatedSolution":29},382,"actualizaciones-seguridad-vps-debian-ubuntu",{"fr":152,"en":153,"ar":154,"es":150},"securite-vps-mises-a-jour-automatiques-debian-ubuntu","vps-automatic-security-updates-debian-ubuntu","تحديثات-أمان-تلقائية-vps-debian-ubuntu","Actualizaciones de seguridad automáticas en VPS Debian\u002FUbuntu","Configure unattended-upgrades en sus VPS Debian\u002FUbuntu para automatizar los parches de seguridad y reducir la superficie de ataque en su flota de clientes.",2,"2026-09-26T00:00:00+00:00","2026-11-09T20:55:15+00:00",{"id":140,"name":161,"slug":162,"color":163,"icon":164},"Seguridad y monitorización","securite-monitoring","bg-rose-500\u002F10 text-rose-400","security",[166],{"id":140,"name":161,"slug":162,"color":163,"icon":164},"\u002Fblog\u002Fcovers\u002Fsecurite-vps-mises-a-jour-automatiques-debian-ubuntu-poster.svg",true,1794270596379]