Skip to content
BotServBotServ
DockerDockerfileMejores prácticasLayerCache

Escribir y optimizar Dockerfile

Dockerfile para principiantes y avanzados. Mejores prácticas, capas, caché y seguridad.

S

schutzgeist

3 min read
Escribir y optimizar Dockerfile

Escribir y optimizar Dockerfiles

Qué cubre este artículo

  • Estructura de un Dockerfile.
  • Instrucciones clave y su orden.
  • Capas, caché y tamaño de imagen.
  • Seguridad y compilaciones limpias.
  • Errores comunes y soluciones.

Introducción: Escribir y optimizar Dockerfiles

Un Dockerfile es la receta para crear una imagen Docker. Define cuál es la imagen base, qué archivos se copian, qué comandos se ejecutan y cómo inicia el contenedor. Un Dockerfile bien escrito produce imágenes pequeñas, seguras y que se compilan rápidamente. Uno mal escrito genera tiempos de compilación prolongados, imágenes enormes y vulnerabilidades de seguridad.

Este artículo explica los fundamentos, las instrucciones clave y las mejores prácticas para Dockerfiles limpios.

Términos clave

  • FROM: Imagen base.
  • RUN: Ejecutar un comando.
  • COPY: Copiar archivos.
  • ADD: Copiar y desempaquetar archivos.
  • CMD: Comando predeterminado al iniciar.
  • ENTRYPOINT: Comando de inicio fijo.
  • WORKDIR: Directorio de trabajo.
  • ENV: Variable de entorno.
  • EXPOSE: Declarar un puerto.
  • USER: Cambiar de usuario.
  • Layer: Capa en la imagen.
  • Cache: Almacenamiento temporal para compilaciones.

Estructura básica

FROM node:20-slim

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .

USER node

EXPOSE 3000

CMD ["node", "server.js"]

Elegir FROM

ImagenTamañoUso
ubuntugrandeCompatibilidad
debian:slimmedioVersátil
alpinepequeñoCompacta, pero musl
distrolessmuy pequeñoMínima, sin shell

Recomendación: Usar imágenes slim oficiales o distroless para contenedores en producción.

Respetar el orden

Docker almacena en caché las capas. Copia primero los archivos que cambian con menos frecuencia:

  1. Imagen base.
  2. Archivos de dependencias.
  3. Instalar dependencias.
  4. Copiar código fuente.
  5. Pasos de compilación.
  6. Comando de ejecución.

Incorrecto:

COPY . .
RUN npm ci

Correcto:

COPY package*.json ./
RUN npm ci
COPY . .

COPY vs ADD

  • COPY simplemente copia archivos.
  • ADD puede procesar URLs y archivos Tar.
  • En la mayoría de los casos, COPY es más seguro y predecible.

Minimizar capas

Cada instrucción RUN, COPY y ADD crea una capa. Menos capas significan imágenes más pequeñas:

RUN apt-get update && \
    apt-get install -y --no-install-recommends curl ca-certificates && \
    rm -rf /var/lib/apt/lists/*

Reducir el tamaño de la imagen

  • Usar .dockerignore.
  • Instalar solo dependencias de producción.
  • Eliminar herramientas de compilación.
  • Usar compilaciones multietapa.
  • No copiar archivos innecesarios.

Ejemplo de .dockerignore:

node_modules
.git
.env
Dockerfile
README.md
tests

Seguridad

  • Usar un usuario sin permisos de root:
RUN useradd -m appuser
USER appuser
  • No incluir secretos en el Dockerfile.
  • No guardar contraseñas en variables de entorno.
  • Mantener permisos mínimos.
  • Usar un sistema de archivos de solo lectura cuando sea posible.

CMD y ENTRYPOINT

CMD es el comando predeterminado, ENTRYPOINT es el comando fijo. Combinación:

ENTRYPOINT ["node"]
CMD ["server.js"]

Verificaciones de salud

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

Comando de compilación

docker build -t mein-image:1.0 .

Forzar la compilación sin caché

docker build --no-cache -t mein-image:1.0 .

Logs y configuración

  • Enviar logs a stdout/stderr.
  • Configuración a través de variables de entorno.
  • No incluir rutas fijas en las imágenes.

Errores comunes

  • Todo en una sola capa: imágenes grandes.
  • Herramientas de compilación en la imagen de ejecución: riesgos de seguridad.
  • Secretos en variables de entorno: visibles en imágenes o logs.
  • Versión FROM incorrecta: usar latest en lugar de tags fijos.
  • Falta .dockerignore: archivos innecesarios en la imagen.
  • Permisos incorrectos: el contenedor se ejecuta como root.
  • CMD en forma de shell: las señales no se transmiten correctamente.

Enlaces y referencias adicionales

FAQ: Dockerfile

¿Qué es un Dockerfile? Un archivo de texto con instrucciones para compilar una imagen Docker.

¿Debo usar COPY . .? Solo con .dockerignore, de lo contrario archivos innecesarios terminan en la imagen.

¿Qué es mejor: Alpine o Debian Slim? Debian Slim tiene mejor compatibilidad, Alpine es más pequeño pero basado en musl.

¿Cómo reduzco el tiempo de compilación? Respeta el orden de las capas, aprovecha el caché y configura .dockerignore.

¿Por qué usar un usuario sin permisos de root? Reduce el riesgo si un contenedor es comprometido.

Fuentes y literatura adicional

Resumen: Escribir y optimizar Dockerfiles

Un buen Dockerfile es clave para compilaciones rápidas, imágenes pequeñas y contenedores seguros. Lo importante es el orden correcto de las instrucciones, el caché efectivo, compilaciones multietapa, .dockerignore, usuarios sin permisos de root y tags de imagen fijos. Quienquiera que siga estos principios evitará problemas típicos y compilará imágenes Docker que funcionen bien tanto en homelab como en producción.

Volver al blog
Share:

Entradas relacionadas