8. Buenas prácticas al usar tus propias imágenes Docker en producción
Fijar una versión concreta de la imagen base (por ejemplo, node:20.11-alpine y no node:latest) evita que una actualización de la imagen base publicada por el proveedor cambie de forma inesperada el comportamiento de tu aplicación tras la siguiente recompilación del contenedor, a menudo sin un aviso claro.
La compilación en varias etapas (multi-stage build) permite mantener pequeña la imagen final de producción, sin herramientas de compilación ni dependencias de desarrollo. Esto acelera la transferencia de la imagen al registro y del registro al servidor de producción, y reduce la superficie de ataque del contenedor.
Las variables de entorno y los secretos (contraseñas, claves API) nunca deben incluirse directamente en una imagen Docker como valores escritos en el Dockerfile, sino pasarse al contenedor en tiempo de ejecución, ya que una imagen construida con un secreto dentro puede llegar a un registro y ser restaurada desde allí por cualquier persona con acceso a ese registro.
Un healthcheck configurado en la imagen o en docker-compose permite detectar automáticamente que el contenedor está en marcha, pero que la aplicación que contiene ha dejado de responder, por ejemplo, si un proceso se ha bloqueado. Sin healthcheck, el problema podría pasar desapercibido porque el contenedor seguiría activo en teoría.
Conviene enviar los logs del contenedor a la salida estándar (stdout/stderr), no a archivos dentro del contenedor. Los logs guardados en archivos se pierden cuando se elimina el contenedor, mientras que los de la salida estándar se pueden recopilar y consultar más fácilmente con las herramientas estándar de Docker.
Revisar periódicamente qué imágenes y etiquetas del registro privado siguen en uso ayuda a mantener todo organizado y liberar el espacio en disco que ocupan las versiones antiguas, ya innecesarias tras sucesivos despliegues de CI/CD.