docker

El gemelo malvado de Postiz

El gemelo malvado de Postiz
Monté una copia de Postiz solo para probar un rediseño. Meses después, sin que nadie lo supiera, ese gemelo llevaba tiempo saboteando al original.
💡 En resumen, para quien tenga prisa

Tenía dos copias de Postiz (la plataforma que programa nuestras publicaciones en redes) corriendo en el mismo servidor: la de producción de verdad, y otra que monté para probar un rediseño responsive. Al levantar la segunda, un fichero de configuración le cambió el nombre a varios contenedores para que no chocaran con los de producción — pero se le olvidó cambiarle también la dirección a uno de ellos. Resultado: el Postiz "de pruebas" llevaba tiempo escribiendo, sin que nadie lo supiera, en la misma base de datos interna que usaba el de producción para coordinar sus publicaciones. Cada vez que arrancaba uno de los dos, ensuciaba el estado del otro. De ahí las publicaciones que fallaban sin patrón aparente.

Para quien no esté metido en esto: usamos Postiz para programar publicaciones en Instagram, Facebook, LinkedIn... de todas las marcas. Por debajo, Postiz no publica él solo — le pasa el encargo a Temporal, un sistema pensado para tareas que tienen que ejecutarse de forma fiable aunque algo falle a mitad de camino (como publicar un post: si se cae el servidor a medio proceso, cuando vuelve tiene que saber por dónde seguía, no repetir el envío ni perderlo). Temporal necesita, para funcionar, su propia base de datos donde llevar la cuenta de quién hace qué.


📉 El síntoma

Me avisaron de que un post de Forvia en Instagram había fallado. Hasta entonces no le di mayor importancia — un fallo suelto, se reintenta y ya. Lo miré, lo arreglé a mano, y seguí con lo mío.

El problema es que no era la primera vez. Y no fue la última.

🐛 El patrón que no era patrón

Publicaciones que fallaban sin ningún motivo visible, de marcas distintas, en momentos distintos, sin que hubiera nada en común entre ellas más allá de "a veces, Temporal no encuentra sus propios servidores".

🕵️ Las pistas falsas

Lo primero que hice fue mirar los logs de Temporal buscando el motivo del fallo. Y no vi prácticamente nada útil — solo mensajes de error sueltos, sin ningún reintento, ninguna advertencia previa, nada que explicara por qué. Pasé un buen rato convencido de que el sistema se había quedado colgado.

No estaba colgado. Estaba progresando perfectamente, registrando decenas de procesos internos uno detrás de otro — pero en silencio, porque en algún momento habíamos configurado el nivel de log al mínimo (solo errores graves) para no llenar la consola de ruido. Nos habíamos puesto la venda nosotros mismos, antes del golpe.

Con el log en modo detallado, empezaron a aparecer avisos de verdad: "no hay suficientes servidores para atender la petición", "espacio de nombres no encontrado" — errores que iban y venían sin ninguna lógica aparente. A veces la misma operación fallaba, y un segundo después funcionaba sin tocar nada.


❓ La pregunta que lo destapó todo

En mitad de la investigación, surgió una duda que hasta ese momento no me había planteado en serio: ¿estás tocando el Postiz que no es? Hay dos — uno de producción, y otro que había montado para probar un rediseño responsive.

Comprobé el contenedor, el puerto, el dominio. Estaba tocando el correcto. Pero la pregunta, aunque la respuesta fuera "no", apuntaba justo donde tenía que apuntar: había dos entornos de Postiz corriendo en la misma máquina. Y nunca me había parado a comprobar si de verdad estaban aislados el uno del otro, más allá de tener nombres de contenedor distintos.

No lo estaban.

🐛 El hallazgo real

El fichero que configuraba el entorno de pruebas le cambiaba el nombre a varios contenedores para evitar chocar con los de producción — la base de datos de pruebas, el motor de búsqueda de pruebas, todo bien renombrado. Todo, menos una cosa: el propio Temporal de pruebas seguía apuntando, en su configuración interna, a los nombres literales de los servidores de producción. Y como esos nombres sí existían de verdad en la red del servidor (eran los de producción), Temporal de pruebas se conectaba a ellos sin quejarse ni avisar de nada raro.

Dos Temporal distintos, escribiendo a la vez sobre la misma tabla interna donde cada uno anota "aquí estoy, esto es lo que llevo". Cada vez que arrancaba cualquiera de los dos entornos, el otro se encontraba con anotaciones que no eran suyas, servidores fantasma que ya no existían, y estado a medio pisar. De ahí los fallos sin patrón: no dependían de qué publicación se enviaba, sino de qué entorno se había reiniciado más recientemente y cuánto ruido había dejado atrás.


🧹 El arreglo, y lo que apareció por el camino

Lo primero, arrancar de raíz: el entorno de pruebas ya no hacía falta, así que lo eliminé entero en vez de parchearlo. Menos superficie, menos riesgo de que volviera a pasar.

Con el entorno de pruebas fuera de la ecuación, el problema debería haber desaparecido. Casi. Quedaban dos fallos sueltos que habían estado ahí todo este tiempo, camuflados detrás del ruido de fondo del problema gordo:

⚠️ El primer sobrante

Uno de los procesos internos se reiniciaba en bucle porque un puerto que usaba para su propio chequeo de salud seguía ocupado por una copia anterior de sí mismo que no había soltado el sitio a tiempo. Ni siquiera es un puerto que haga falta para publicar — solo para que el propio sistema se compruebe a sí mismo. Bastó con que, si no consigue ese puerto, avise y siga funcionando en vez de morir por ello.
⚠️ El segundo sobrante

El código que arranca cada publicación llamaba a una versión de la tarea interna que, en el servidor de verdad, ya no existía con ese nombre — se había quedado desactualizada respecto a lo que había en producción. Un grep por el nombre correcto y listo, pero hasta no encontrarlo, cada intento de publicar fallaba con un error que no tenía nada que ver con el problema original.

Con las tres cosas resueltas, disparé de nuevo las publicaciones que se habían quedado atascadas — empezando por la de Forvia, la que había arrancado todo esto. Publicó. Las demás, detrás.


📋 Antes / después

Antes Ahora
Entornos de Postiz en el servidor Dos, compartiendo sin saberlo la misma base interna de Temporal Uno solo, el de producción
Nivel de log Solo errores graves — silenciaba avisos útiles Detallado cuando hace falta investigar
Fallos de publicación Sin patrón aparente, intermitentes, "nos pasa bastante" Resueltos, con causa identificada
Confianza al levantar un entorno "solo para probar algo" Ninguna comprobación de aislamiento real Verificar que ni una sola variable de conexión apunte a producción

🎓 La moraleja

Durante horas eché la culpa mentalmente a Temporal: parecía errático, poco fiable, difícil de depurar. No era así. Temporal hacía exactamente lo que se le pedía — el problema era que se le pedían dos cosas contradictorias a la vez, desde dos entornos que yo daba por aislados sin haberlo comprobado nunca de verdad.

"Es solo para pruebas" no significa nada si no lo compruebas variable por variable. Un nombre de contenedor distinto no es aislamiento — es maquillaje. El entorno de pruebas nunca tuvo mala intención: simplemente hacía, con toda la fidelidad del mundo, exactamente lo que su configuración a medias le decía que hiciera.

Y la pregunta que de verdad destapó el problema no fue una respuesta técnica — fue alguien dudando en voz alta de si estaba mirando donde tenía que mirar. A veces hace falta eso, no otro log más.

Nebula Systems
Escrito por

Nebula Systems