¿Por qué tu imagen de Docker tiene la mitad del tamaño que la mía?
Recuerdo que un desarrollador junior me preguntó esto una vez después de comparar nuestras compilaciones de Docker para la misma aplicación Node.js.
Teníamos la misma imagen base. Las mismas dependencias. La misma aplicación. Pero mi compilación era más ligera, más rápida y más fácil de depurar.
¿Cuál es el secreto?
No hay magia.
Solo experiencia.
En este artículo, te mostraré 5 trucos reales de Dockerfile que los desarrolladores senior utilizan a diario, trucos que ahorran tiempo, reducen la sobrecarga y hacen que los contenedores estén más preparados para la producción.
Cada uno se explica en detalle, con ejemplos que realmente funcionan.
Truco n.º 1: minimizar las capas
Supongamos que estás configurando una imagen basada en Debian y necesitas instalar algunas herramientas:
# Junior way
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get cleanCada instrucción RUN crea una nueva capa de imagen. Esto no solo aumenta el tamaño de la imagen, sino que también ralentiza la compilación y el uso de la caché.
Así es como lo hacen los expertos:
# Senior way
RUN apt-get update && \
apt-get install -y curl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*Por qué es importante:
- Combinar comandos en un único
RUNreduce las capas. rm -rf /var/lib/apt/lists/*borra los metadatos temporales de los paquetes, lo que ahorra MB.- El
&&garantiza que, si falla un comando, la compilación se detiene inmediatamente.
Prueba esto:
Ejecuta docker build en ambas versiones y compara los tamaños de las imágenes:
docker imagesVerás que la versión senior es significativamente más pequeña y limpia.
Truco n.º 2: utiliza .dockerignore
No subirías tu carpeta .git a producción, así que ¿por qué incluirla en tu contexto Docker?
Por defecto, todo lo que hay en tu contexto de compilación se envía al demonio Docker, a menos que lo ignores explícitamente.
El problema:
# Without .dockerignore
COPY . .Si tu carpeta local contiene:
node_modules/.git/logs/- datos de prueba...
Todos ellos se copian, lo que ralentiza la compilación y sobrecarga la imagen.
La solución:
Crea un archivo llamado .dockerignore en la raíz de tu proyecto:
node_modules
.git
*.log
DockerfileAhora solo se incluirán los archivos relevantes.
Consejo profesional:
Ejecute esto para ver qué se envía realmente a Docker:
docker build . --no-cache --progress=plainTruco n.º 3: compilaciones en varias etapas para obtener imágenes limpias y listas para la producción
Esta es una de las características más potentes de Docker que los principiantes suelen pasar por alto.
Escenario:
Estás creando una aplicación React.
Necesitas node para crearla, pero no para servirla.
Archivo Dockerfile principiante:
FROM node:18
WORKDIR /app
COPY . .
RUN npm install && npm run build
CMD ["npx", "serve", "build"]Esto mantiene todas las herramientas de compilación en la imagen final, lo que supone una sobrecarga innecesaria.
Archivo Dockerfile sénior (multietapa):
# Stage 1: Builder
FROM node:18 as builder
WORKDIR /app
COPY . .
RUN npm install && npm run build
# Stage 2: Production
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/htmlVentajas:
- La imagen final es muy pequeña.
- Sin node_modules, sin código fuente, sin herramientas de compilación.
- Seguro y rápido.
Esto resulta especialmente útil para:
- Aplicaciones front-end
- Aplicaciones Java (compilaciones Maven/Gradle)
- Aplicaciones Go (salida binaria estática)
Compilar y ejecutar:
docker build -t myapp .
docker run -p 80:80 myappTu aplicación se servirá desde nginx, sin nodo a la vista.
Truco n.º 4: fijar versiones de imágenes
Esto provoca pesadillas en producción.
La forma arriesgada:
FROM python:latestHoy funciona. Pero, ¿qué pasa si la última se actualiza mañana?
Tu compilación podría fallar. Tu aplicación podría bloquearse.
La forma segura:
FROM python:3.11.6-slimFijar siempre a:
- Una versión específica
- Una variante mínima (
slim,alpine) cuando sea posible
Por qué es importante:
docker pull python:latest
docker pull python:3.11.6-slimCompare los tamaños y piense en la fiabilidad durante CI/CD.
Advertencia:
No utilice alpine a ciegas con todos los lenguajes, ya que algunas bibliotecas no se compilan debido a la incompatibilidad de musl. Pruébelo siempre.
Truco n.º 5: utilice HEALTHCHECK para añadir la autorreparación a sus contenedores
Una de las características de un ingeniero sénior es la creación de sistemas que pueden recuperarse de los fallos de forma automática.
Eso es exactamente lo que le permite hacer HEALTHCHECK de Docker.
Lo que los juniors suelen pasar por alto:
la mayoría de los Dockerfiles de nivel junior simplemente ejecutan la aplicación:
CMD ["node", "server.js"]Pero no hay forma de saber si la aplicación sigue funcionando una vez que se inicia el contenedor.
- ¿Qué pasa si la aplicación se cuelga?
- ¿Qué pasa si lanza una excepción pero el proceso no se bloquea?
- ¿Qué pasa si se inicia correctamente pero falla al cabo de unos minutos?
Docker mostrará felizmente el contenedor como «en ejecución», incluso si la aplicación que hay dentro está dañada.
Dockerfile de nivel superior:
Los desarrolladores senior definen un HEALTHCHECK para verificar periódicamente que la aplicación sigue funcionando como se espera.
HEALTHCHECK --interval=30s --timeout=10s \
CMD curl -f http://localhost:8080/health || exit 1Esto ejecuta una solicitud curl cada 30 segundos.
- Si devuelve 200 → Docker sabe que el contenedor está bien.
- Si falla → Docker marca el contenedor como defectuoso.
Analicémoslo:
--interval=30s: Ejecuta la comprobación cada 30 segundos.--timeout=10s: Falla la comprobación si tarda más de 10 segundos.--start-period=10s: Da a la aplicación 10 segundos para iniciarse antes de comenzar las comprobaciones de estado.--retries=3: Marca el contenedor como no operativo solo si fallan 3 comprobaciones seguidas.CMD: El comando de comprobación de estado real; en este caso, utilizamos/health.
Cómo ayuda en proyectos reales:
- En desarrollo, te ayuda a detectar fallos tempranos mientras se inicia la aplicación.
- En staging o producción, herramientas como Docker Swarm, Kubernetes y ECS reinician automáticamente los contenedores marcados como no operativos.
- En los procesos de CI/CD, te da más confianza de que tu contenedor se ha iniciado correctamente antes de ejecutar pruebas o promocionarlo.
Incluso puedes definir una lógica personalizada, como comprobar si existe un archivo, si un puerto está abierto o si una conexión de base de datos está activa.
Consejo extra:
Si tu aplicación no expone un punto final HTTP /health, tal vez porque se trata de una herramienta CLI, un servidor TCP o un trabajador en segundo plano, puedes seguir utilizando HEALTHCHECK para supervisar el proceso.
Prueba algo como esto:
HEALTHCHECK --interval=30s --timeout=10s \
CMD pgrep myserver || exit 1Qué hace:
pgrep myservercomprueba si el proceso denominadomyserverse está ejecutando actualmente dentro del contenedor.Si encuentra el proceso → sale con 0, marcando el contenedor como en buen estado.- Si el proceso no se está ejecutando → sale con un estado distinto de cero, marcándolo como en mal estado.
Este enfoque es especialmente útil cuando:
- Tu servicio no utiliza HTTP.
- Estás ejecutando un binario o script que no tiene un punto final de estado.
- Está trabajando con sistemas heredados o demonios de larga duración.
Ejemplo real:
Supongamos que tiene una aplicación Java ejecutándose con este comando:
CMD ["java", "-jar", "myapp.jar"]Entonces, tu chequeo médico podría ser:
HEALTHCHECK CMD pgrep java || exit 1Es una forma sencilla pero eficaz de garantizar que el proceso principal no se haya bloqueado ni haya salido silenciosamente.
Reflexiones finales
Estos trucos de Dockerfile no son ciencia espacial avanzada. Son hábitos prácticos que hacen que tus contenedores sean más rápidos, más pequeños y más seguros.
Recapitulemos:
Combina los comandos RUN para reducir las capas de la imagen.
Utiliza .dockerignore para acelerar las compilaciones.
Aplica compilaciones multietapa para crear imágenes de producción optimizadas.
Fija las versiones para evitar sorpresas en el futuro.
Añade HEALTHCHECKs para la supervisión y la resiliencia.
La próxima vez que trabajes con Docker, prueba a aplicar uno o dos de estos trucos y comprueba cómo tu configuración se vuelve mucho más limpia.
Gracias por leer Codigo en Casa.Si esto te a ayudado y te sumo algo Dale un 👏 , compártelo con tu red o dejame un comentario para saber tu opinión.