[{"data":1,"prerenderedAt":166},["ShallowReactive",2],{"seo-verification":3,"blog-docker-compose-actualizacion-buenas-practicas-vps-es":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-docker-compose-actualizacion-buenas-practicas-vps-es",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":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.",9,0,false,"2026-10-09T00:00:00+00:00","2026-10-09T22:36:09+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. Los cambios disruptivos recientes en Meilisearch v1.54, Supabase PostgreSQL 15→17, Langfuse v3→v4 y NocoDB 2026.09 lo confirmaron duramente: instancias de producción estables durante meses, inutilizables 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\nEsto es exactamente lo que ocurrió con **Meilisearch v1.54**. Esta versión introdujo un nuevo formato de almacenamiento vectorial por defecto (cambio de arroy a HNSW) que hace el directorio de datos incompatible con versiones anteriores. Al iniciarse, Meilisearch rechaza abrir la base de datos y entra en crash-loop. El único camino de recuperación limpio es crear un dump antes de la actualización — imposible una vez que el contenedor está bloqueado.\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: meili\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 (lanzado el 17 de agosto 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 db pg_dump -U postgres -Fc mydb > backup_$(date +%Y%m%d_%H%M%S).dump\n```\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 v1.54, 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 v1.53 → v1.54** (2026): introducción del almacén vectorial HNSW como formato por defecto. Meilisearch se niega a abrir un índice creado con el antiguo formato arroy. El arranque entra en crash-loop con `Your database version is incompatible with your current engine version`. La única salida limpia es haber exportado un dump antes de la actualización — importarlo en la nueva versión restaura tus datos.\n\n**Supabase Docker PostgreSQL 15 → 17** (migración activada 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** (GA el 17 de agosto 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** desde el momento en que arranca el stack v4. Si tus servicios cliente no han migrado antes de la actualización del servidor, pierden silenciosamente todos sus trazados.\n\n**NocoDB 2026.09.x**: la serie 2026.09 reconstruye las imágenes Docker para eliminar dependencias vulnerables. Las instalaciones que usan bind-mounts (`.\u002Fpostgres`, `.\u002Fnocodb`) en lugar de volúmenes nombrados pueden arrancar sobre una base de datos vacía tras el pull — NocoDB no encuentra sus datos si la ruta de montaje cambió entre versiones. Se recomienda migrar a volúmenes nombrados antes de actualizar.",{"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,130,146],{"id":115,"slug":116,"slugs":117,"title":121,"excerpt":122,"readTime":123,"views":18,"isPinned":19,"publishedAt":124,"updatedAt":125,"category":126,"categories":127,"featuredImage":29,"bgImage":30,"posterImage":129,"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","Checklist de Docker Compose en producción: 10 ajustes esenciales, health checks, secretos sin downtime, estrategia de rollback, solución de errores comunes.",12,"2026-08-06T00:00:00+00:00","2026-09-29T14:40:45+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},[128],{"id":23,"name":24,"slug":25,"color":26,"icon":25},"\u002Fblog\u002Fcovers\u002Fdocker-compose-production-checklist-poster.svg",{"id":131,"slug":132,"slugs":133,"title":137,"excerpt":138,"readTime":139,"views":18,"isPinned":19,"publishedAt":140,"updatedAt":141,"category":142,"categories":143,"featuredImage":29,"bgImage":30,"posterImage":145,"relatedSolution":29},282,"docker-compose-healthcheck-postgresql",{"fr":134,"en":135,"ar":136,"es":132},"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,"2026-08-19T00:00:00+00:00","2026-09-07T11:26:10+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":25},[144],{"id":23,"name":24,"slug":25,"color":26,"icon":25},"\u002Fblog\u002Fcovers\u002Fdocker-compose-depends-on-healthcheck-poster.svg",{"id":147,"slug":148,"slugs":149,"title":153,"excerpt":154,"readTime":155,"views":18,"isPinned":19,"publishedAt":156,"updatedAt":157,"category":158,"categories":163,"featuredImage":29,"bgImage":30,"posterImage":165,"relatedSolution":29},382,"actualizaciones-seguridad-vps-debian-ubuntu",{"fr":150,"en":151,"ar":152,"es":148},"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.",10,"2026-09-26T00:00:00+00:00","2026-09-29T14:40:42+00:00",{"id":139,"name":159,"slug":160,"color":161,"icon":162},"Seguridad y monitorización","securite-monitoring","bg-rose-500\u002F10 text-rose-400","security",[164],{"id":139,"name":159,"slug":160,"color":161,"icon":162},"\u002Fblog\u002Fcovers\u002Fsecurite-vps-mises-a-jour-automatiques-debian-ubuntu-poster.svg",1791585794279]