En este episodio me toca contarte una historia de terror, o mejor dicho, una historia de un poltergeist en Docker. Y es que, hace unos días, me encontré con un problema bastante extraño en mi entorno de Docker, que me hizo pensar que tenía un poltergeist rondando por allí. Quizá con esto de una historia de terror, me he pasado un poco, pero seguro que si te digo que durante unas horas me cayeron unas gotas de sudor frío, seguro que sabes a que me refiero. La cuestión es que finalmente acabó bastante mal, aunque ya sabes que siempre puede terminar peor.
El Poltergeist de Docker que casi borra toda mi información
Preliminares
Hace ya tiempo que decidí que dedicaría un contenedor de base de datos para cada uno de los servicios en lugar de tener un único contenedor común para todos los servicios.
Siempre surge la pregunta de ¿que es mejor?, ¿uno para todos? o ¿uno para cada uno?. Yo desde el principio me decanté por la segunda opción, y la verdad es que no me arrepiento en absoluto. Tener un contenedor de base de datos para cada servicio me permite tener una mayor flexibilidad a la hora de configurar cada uno de los servicios, y también me permite tener una mayor seguridad, ya que si un servicio se ve comprometido, no afecta al resto de servicios.
Pero además, está el asunto de las versiones. Hay servicios que por la razón que sea utilizan una determinada versión de base de datos y no es compatible con otras versiones. Tener un contenedor de base de datos para cada servicio me permite tener la versión que necesito para cada uno de los servicios sin tener que preocuparme por las incompatibilidades.
Los hechos
Hace unos días todas las instancias de PostgtresSQL que tenía en Docker, empezaron a caer como chinches. Al principio pensé que era una única instancia la que estaba dando problemas, pero al final me di cuenta de que todas las instancias de Postgres que se habían reiniciado porque se había actualizado algún servicio del stack. Quiero decir, no es que se hubiera actualizado el propio Postgres, lo que se había actualizado era alguno de las imágenes del stack. Una vez reiniciado el stack era cuando había fallado Postgres y comenzaba un ciclo de reinicios continuos.
Como te puedes imaginar esto no se me ocurrió al principio, ni remotamente. Mi primer pensamiento fue exactamente igual que el tuyo, y lo que me había ocurrido además recientemente con la actualización de Posgtres de las versión 17 a la 18. Pensaba que había llegado una actualización de la imagen de Posgtres. Pero no, realmente no era eso lo que había sucedido.
Mi reacción
Como te puedes imaginar, mi primera reacción fue detener todos los stacks que se estaban reiniciado continuamente. Fue justo ahí donde me di cuenta que no eran todos los Postgres los que se estaban reiniciando.
Intenté reiniciar uno de ellos, en concreto el de miniflux. Al repasar la configuración, vi que tenía configurado Postgres versión 18 con Alpine Linux. Al iniciar el stack, todo parecía ir bien, pero al cabo de unos segundos, el contenedor de Postgres se reiniciaba. Intenté revisar los logs, pero no había nada que me diera una pista clara de lo que estaba sucediendo.
Aquí fue cuando pensé que había sido una actualización de la imagen de Posgres. Estuve repasando y probando distintas configuraciones y cambiando las imágenes. Y nada de nada. No conseguía resolver el problema.
Te puedes imaginar que hice una barbaridad de pruebas, tanto con distintas configuraciones como con distintas imágenes. No había forma.
El poltergeist
Llegados a este punto, me centré únicamente en intentarlo con la imagen de Postgres 18-alpine, con lo que di por perdido todo lo que tenía en miniflux. Que para colmo de males, no había guardado… Ahora que lo he recuperado todo, tampoco tengo una copia de lo que hay en miniflux.
Paré el stack, lo inicié, y cuando parecía que todo había arrancado correctamente, volvía al ciclo de reinicios constantes. Y fue justo aquí donde apareció el poltergeist. Cuando iniciaba el arranque tenía un 18-alpine, pero al parar de nuevo el stack se había convertido en un 18rc1-trixie.
postgres 18-alpine ff4a089dadda 5 days ago 286MB
postgres 18rc1-trixie a6ef897077cd 5 months ago 456MB
Los errores que daba justo se correspondían con esa versión 18rc1-trixie.
Lo intenté varias veces. Borraba la imagen, descargaba la imagen 18-alpine, iniciaba y de nuevo, magia, aparecía que todo había arrancado correctamente, pero al parar de nuevo el stack se había convertido en un 18rc1-trixie.
La cuestión es que cada vez que hacía esta operación de eliminar trixie y reiniciar el stack descargaba la imagen. Estaba totalmente sorprendido.
Los nervios
En este punto, me entró los nervios, el pánico y la flojera, y en lugar de pensar fríamente a ver que pudiera ser, hice lo peor, lo que siempre hago en estos casos y lo que nunca debería hacer, borrar.
Al ver que la imagen aparecía una y otra vez, a pesar de que yo la borraba y volvía a borrar, me lancé a borrar todo, digo a limpiar. Empecé solo por las imágenes, pero como no se resolvía continué con un docker system prune y así sucesivamente.
Y aquí fue cuando aparecieron esos sudores fríos que te mencionaba al inicio del episodio. En ese momento caí en que tenía varios stacks parados, y con todos esos prune había perdido todo el contenido de los mismos. Si, algunos tenían copias de seguridad y otros no, porque el contenido no era vital, pero… si los quería tenía que volver a reconstruirlo todo.
El analizador de logs
Hace meses que he dejado de interpretar logs. Esto de investigador forense queda muy bien pero la realidad es que es verdaderamente tedioso. Sobre todo cuando los logs aparecen con caracteres extraños, pero en general, es realmente muy cansado.
Así que decidí hace ya tiempo, hacer uso de Gemini para analizar los logs. Simplemente copio la parte donde intuyo que está el error, y se lo paso a Gemini para que me lo analice. Y la verdad es que me ha dado muy buenos resultados.
Justo aquí es donde me dio la pista, y además de forma clara, el mensaje fue el culpable mas probable: Watchtower.
El culpable
A pesar de que Gemini había apuntado un posible culpable, la realidad es que no, el realmente no era el culpable. El culpable era What’s up Docker. Y te estarás preguntado que como lo averigüé, pues de la forma mas sencilla, simplemente parando el servicio.
Probablemente, me digas que esto no puede suceder, que WUD solo notifica, que … Lo que quieras, pero, la realidad más real es que fue parar el servicio y desaparecer el poltergeist, con lo que opté por la opción más razonable, desinstalar el servicio. Que, por otra parte, te tengo que decir, que pensaba que ya no lo tenía instalado. Menudo desastre.
Conclusión los actualizadores automáticos los carga el diablo. Cada vez tengo mas claro, que el camino que emprendí de migrar a Podman, es el camino correcto. En Podman, el encargado de actualizar es el propio Podman, no es un servicio de terceros.