3.5Depuración de Compose : reinicios y volúmenes huérfanos
Lo esencial en 30 segundos
- « Restarting » : leer antes de recrear : compose ps localiza al enfermo, logs del servicio lo acusa — se corrige el ARCHIVO, luego up -d solo recrea lo que cambia.
- Puerto ocupado : se mueve el izquierdo : 8080 already in use = okupa en el host — se cambia el puerto host (izquierdo), nunca el interno ; docker ps global desenmascara.
- Builds viejos, volúmenes huérfanos : apuntar : up -d --build tras modificar el código, volume ls para los huérfanos — down -v solo toca ESTE proyecto, con prudencia.
Mini-caso hilado — Idir y el puerto fantasma
Idir, devops junior en Argel, lanza su stack un lunes : la api entra en bucle Restarting, « port already allocated ». En lugar de arrasarlo todo, diagnostica : compose ps localiza la api, compose logs acusa al puerto, docker ps global desenmascara un viejo run manual olvidado en 8080. Cambia el puerto HOST a 8082 en el compose, up -d — el stack arranca, los datos intactos. El fantasma manual se limpia después, quirúrgicamente. Desde entonces, Idir lee antes de recrear.
Este mismo caso vuelve en el curso, el esquema, el guion y el reto 48h.
1. Restarting y puerto ocupado : ps localiza, logs acusa
Servicio en « Restarting » : se LEE antes de recrear. docker compose ps localiza al enfermo, logs nombre-del-servicio lo acusa — variable ausente, volumen en ruta errónea, puerto ocupado. Se corrige el ARCHIVO, luego up -d : Compose solo recrea lo que cambia, el resto sigue corriendo. Lo declarativo es quirúrgico por naturaleza : se cura la descripción, no los contenedores.
El puerto ya usado (8080 already in use) : otro servicio — o un antiguo run fuera de Compose — ocupa el puerto HOST. Solución : cambiar el puerto host (el izquierdo, "8082:80"), nunca el puerto contenedor ; docker ps global desenmascara al okupa. Dos stacks que se mezclan suelen ser el mismo nombre de proyecto (carpeta) o los mismos puertos host : aísle con -p y puertos distintos.
2. Builds viejos y volúmenes huérfanos : apuntar, no arrasar
¿El código no se actualiza tras un up ? La imagen no se ha reconstruido : up -d --build, no un rm furioso. Renombrar un servicio o un proyecto crea volúmenes huérfanos (datos antiguos dormidos) : docker volume ls los muestra, y compose down -v solo toca ESTE proyecto — con prudencia, porque borra sus volúmenes. Limpiar es identificar primero.
Los tres reflejos del médico del stack : nombrar los proyectos (-p) en caso de duplicados, leer los logs del servicio (no todo el stack), corregir el archivo y relanzar. Y la prohibición absoluta : down -v en pánico — nunca se arrasa para diagnosticar. Idir ha pegado la secuencia en la pared : ps → logs → corregir → up -d.
🔎 Ejemplo concreto — Puerto ocupado por un fantasma : diagnóstico completo
Idir despliega la secuencia ps → logs → docker ps → corrección del archivo.
docker compose ps # api : Restarting ?
docker compose logs api # Error: puerto ya usado ?
docker ps # ¿un viejo run manual en 8080 ?
# Corregir el puerto HOST en compose.yml : "8082:80"
docker compose up -d # solo recrea lo que cambia
Lectura : el okupa era un run manual olvidado — desenmascarado por el ps global.
Lección : se cambia el puerto host (izquierdo), nunca el interno ; se limpia el fantasma después.
Vocabulario de la sección
- Huérfano
- Volumen o proyecto abandonado tras un renombrado : datos antiguos dormidos por identificar antes de toda limpieza.
Ejemplo sencillo: El antiguo pgdata de Idir tras renombrar el servicio.
Lo que no es: un volumen activo del proyecto actual.
Reflejo: volume ls primero, suprimir con conocimiento de causa.
- Okupa
- Proceso que ya ocupa el puerto host buscado : viejo run manual o segundo stack en el mismo puerto.
Ejemplo sencillo: El run manual olvidado en 8080.
Lo que no es: un problema en la imagen del servicio.
Reflejo: docker ps global para desenmascarar.
- --build
- Forzar la reconstrucción de las imágenes en el up : el código modificado se aplica de verdad.
Ejemplo sencillo: El up -d --build de Idir tras cada cambio de api.
Lo que no es: un rm furioso de los contenedores para « forzar ».
Reflejo: código cambiado = --build, sistemático.
- Nombre de proyecto
- Prefijo que aísla los recursos de un stack (-p, carpeta por defecto) : dos proyectos, dos mundos.
Ejemplo sencillo: Idir aísla maqueta y bac con -p.
Lo que no es: dos stacks que se mezclan en los mismos puertos.
Reflejo: nombrar en caso de duplicados en una máquina.
- Recrear (selectivo)
- up -d solo recrea los servicios modificados : la cirugía de lo declarativo, el resto corre.
Ejemplo sencillo: Solo la api recreada tras el cambio de puerto.
Lo que no es: arrasarlo todo « para estar seguro ».
Reflejo: corregir el archivo, relanzar, verificar.
En la práctica — Romper y reparar, con bisturí
- Provoque un puerto ocupado : run manual + compose en el mismo puerto host.
- Diagnostique : compose ps, compose logs del servicio, docker ps global.
- Corrija el puerto host en el archivo y relance (up -d) : solo cambia el servicio.
- Limpie el fantasma manual (rm -f) y verifique : stack en verde, datos intactos.
Guion listo para decir — anunciar la avería y el remedio (30 s)
« La api entraba en bucle : puerto host okupado por un viejo run manual olvidado. Moví el puerto izquierdo a 8082 en el compose, relancé — solo se recreó el servicio, datos intactos, fantasma limpiado después. Sin down -v, sin pérdida. »
Para decir en reunión de equipo ; mostrar la secuencia ps → logs → corrección.
Modelo copiar-pegar — compose tras corrección del puerto
# Tras diagnóstico : puerto host movido (izquierdo), interno sin cambios.
services:
web:
image: nginx:1.27
ports:
- "8082:80"
networks:
- front
bdd:
image: postgres:16.4
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- front
volumes:
pgdata:
networks:
front:
# Diagnóstico : compose ps, logs del servicio, docker ps global.
Independiente
La secuencia ps → logs → corregir → up -d y sus lunes por la mañana vuelven a la calma.
PYME en Argel
Idir pega la secuencia en la pared : el equipo diagnostica antes de arrasar.
Equipo de proyecto
Prohibir el down -v fuera del stack desechable ; exigir el log del servicio en cada ticket de avería.
Principiante
Esta semana : provoque un puerto ocupado en desechable y repárelo con bisturí.
✓ Buenas prácticas
- Lea los logs del servicio preciso, no todo el stack en desorden.
- Corrija el archivo, relance : Compose solo recrea lo que cambia.
- Nombre los proyectos (-p) en cuanto dos stacks compartan una máquina.
✗ Errores frecuentes
- down -v en pánico : los datos del proyecto se borran.
- Cambiar el puerto contenedor (derecha) en lugar del puerto host (izquierda).
- Olvidar --build tras modificar el código : la imagen antigua sigue corriendo.
Puntos clave
- PS localiza, LOGS acusa, el ARCHIVO corrige : leer antes de recrear.
- PUERTO ocupado → se mueve el puerto HOST (izquierdo) o se elimina al okupa.
- DOWN -v = reset del proyecto, con prudencia — nunca un diagnóstico.
- --BUILD tras cada cambio de imagen ; -p para aislar los duplicados.
Reto 48h — aplique mañana
Provoque 1 avería en desechable (puerto ocupado) y repárela sin -v, anotando cada paso del diagnóstico.
- Diagnostico ps → logs antes de toda acción.
- Muevo el puerto host, nunca el interno.
- Nunca arraso : -v solo en reset decidido.
Preguntas frecuentes
¿Por qué se mezclan dos stacks ?
Mismo NOMBRE DE PROYECTO (la carpeta por defecto) o mismos PUERTOS HOST : los recursos se solapan. Aísle con -p nombre-proyecto y puertos host distintos. compose ps por proyecto muestra entonces dos mundos separados — y docker ps global sigue siendo el árbitro en caso de duda.
¿Hay que recrearlo todo cuando cambia un servicio ?
NO : up -d solo recrea los servicios modificados — ese es todo el valor de lo declarativo. Corrija el archivo, relance, verifique : el resto sigue corriendo, los volúmenes quedan. Arrasarlo todo « para estar seguro » destruye lo que lo declarativo preserva.
Compose muestra « port already allocated ». ¿Qué cambia ?