certmundo.
es‑mx

6 min de lectura

¿Cómo crear tu propio Dockerfile desde cero?

Un Dockerfile es un archivo de texto con instrucciones paso a paso que le dicen a Docker cómo construir tu imagen personalizada.

Imagina que trabajas en el equipo de tecnología de Liverpool. Tienes una aplicación Python que calcula descuentos para el programa de lealtad. Funciona perfecto en tu laptop, pero cuando la subes al servidor de producción, todo falla. Las versiones de librerías no coinciden, falta una dependencia, y el equipo de operaciones no sabe qué instalar. Ese problema clásico —"en mi máquina sí funciona"— es exactamente lo que un Dockerfile resuelve.

El sistema RECETA-IMAGEN

Piensa en el Dockerfile como una receta de cocina. La receta (Dockerfile) siempre produce el mismo platillo (imagen), sin importar en qué cocina (servidor) la prepares. Este sistema se llama RECETA-IMAGEN y tiene tres momentos:

  1. Escribes el Dockerfile con las instrucciones.
  2. Construyes la imagen con docker build.
  3. Ejecutas contenedores desde esa imagen en cualquier servidor.

Cada instrucción en el Dockerfile agrega una capa a la imagen. Docker apila esas capas como transparencias sobre un proyector: cada una agrega algo nuevo sobre lo anterior.

Las cinco instrucciones esenciales

No necesitas memorizar decenas de comandos. Con estas cinco instrucciones puedes empaquetar el 90% de las aplicaciones reales:

FROM — El punto de partida

FROM le dice a Docker sobre qué base construirás tu imagen. Siempre es la primera instrucción.

FROM python:3.11-slim

Esta línea descarga la imagen oficial de Python 3.11 en su versión ligera (slim). Nunca uses FROM python:latest en producción. La versión exacta garantiza que tu imagen funcione igual hoy y dentro de seis meses.

WORKDIR — Tu carpeta de trabajo

WORKDIR define el directorio donde Docker ejecutará los comandos siguientes. Es como hacer cd antes de trabajar.

WORKDIR /app

A partir de aquí, todo sucede dentro de /app. Si la carpeta no existe, Docker la crea automáticamente.

COPY — Llevar tus archivos al contenedor

COPY copia archivos desde tu máquina hacia la imagen.

COPY requirements.txt .
COPY app.py .

El punto (.) significa "copia aquí", es decir, dentro del WORKDIR que definiste. Primero copia requirements.txt antes que el código porque Docker reutiliza capas anteriores si no cambiaron. Así, si solo editas app.py, Docker no reinstala las dependencias desde cero.

RUN — Ejecutar comandos durante la construcción

RUN ejecuta comandos mientras Docker construye la imagen. Úsalo para instalar dependencias.

RUN pip install --no-cache-dir -r requirements.txt

El flag --no-cache-dir evita que pip guarde archivos temporales dentro de la imagen. Tu imagen queda más ligera.

CMD — El comando al arrancar el contenedor

CMD define qué se ejecuta cuando alguien corre un contenedor basado en tu imagen.

CMD ["python", "app.py"]

Usa siempre el formato de lista (con corchetes). Ese formato se llama "exec form" y es más confiable que escribirlo como texto plano.

Ejemplo completo: aplicación de descuentos de Liverpool

Supon que tienes estos dos archivos en tu carpeta de proyecto:

requirements.txt

flask==3.0.0

app.py

from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/descuento/<int:precio>")
def calcular_descuento(precio):
    descuento = precio * 0.15
    precio_final = precio - descuento
    return jsonify({
        "precio_original": f"${precio:,.0f}",
        "descuento_15": f"${descuento:,.0f}",
        "precio_final": f"${precio_final:,.0f}"
    })

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

Ahora crea un archivo llamado exactamente Dockerfile (sin extensión) en esa misma carpeta:

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .

CMD ["python", "app.py"]

Este Dockerfile le dice a Docker:

  1. Parte de Python 3.11 slim.
  2. Trabaja en la carpeta /app.
  3. Copia e instala las dependencias.
  4. Copia el código.
  5. Al arrancar, ejecuta python app.py.

Cómo construir y ejecutar tu imagen

Abre tu terminal en la carpeta del proyecto y ejecuta:

docker build -t liverpool-descuentos:1.0 .
  • -t liverpool-descuentos:1.0 le pone nombre y versión a tu imagen.
  • El punto final (.) le dice a Docker dónde está el Dockerfile (en la carpeta actual).

Verás cómo Docker ejecuta cada instrucción y muestra el progreso capa por capa. Al terminar, prueba con:

docker run -d -p 5000:5000 liverpool-descuentos:1.0

Abre tu navegador en http://localhost:5000/descuento/1200 y verás algo así:

{
  "precio_original": "$1,200",
  "descuento_15": "$180",
  "precio_final": "$1,020"
}

Tu aplicación corre dentro de un contenedor. Cualquier servidor con Docker puede ejecutar exactamente esto, sin instalar Python ni Flask manualmente.

Errores comunes al escribir un Dockerfile

Error 1: Copiar todo antes de instalar dependencias

Muchos principiantes escriben esto:

COPY . .
RUN pip install -r requirements.txt

El problema: cada vez que cambias cualquier archivo, Docker reinstala todas las dependencias desde cero. Eso puede costar varios minutos extra en cada build. La solución es copiar primero requirements.txt, instalar, y luego copiar el resto del código.

Error 2: Usar latest como versión base

FROM python:latest  # ❌ Peligroso
FROM python:3.11-slim  # ✅ Correcto

latest cambia con el tiempo. Una imagen que funcionaba hoy puede romperse mañana cuando Python libere la versión 3.13. En un equipo como el de FEMSA, donde decenas de servicios dependen entre sí, eso puede causar un apagón de producción.

Error 3: Olvidar el .dockerignore

Cuando usas COPY . ., Docker copia absolutamente todo, incluyendo tu carpeta .git, archivos de configuración local, contraseñas en .env, y carpetas node_modules o __pycache__ que pesan cientos de megabytes.

Crea un archivo .dockerignore junto a tu Dockerfile:

.git
__pycache__
*.pyc
.env
venv/

Así Docker ignora esos archivos al construir la imagen. Tu imagen queda más pequeña y más segura.

Error 4: Ejecutar la app como root

Por defecto, los procesos dentro del contenedor corren como usuario root. Eso es un riesgo de seguridad. En entornos de producción, como los que usa Mercado Libre para sus microservicios, siempre se crea un usuario sin privilegios:

RUN adduser --disabled-password --gecos "" appuser
USER appuser
CMD ["python", "app.py"]

Con USER appuser, el proceso ya no tiene permisos de root dentro del contenedor.

Comparación: con Dockerfile vs. sin Dockerfile

Situación Sin Docker Con Dockerfile
Nuevo desarrollador en el equipo Instala Python, pip, librerías manualmente (1–2 horas) docker build y listo (5 minutos)
Servidor de producción Puede tener versión distinta de Python Siempre la misma versión exacta
Error "en mi máquina sí funciona" Frecuente Prácticamente imposible
Rollback a versión anterior Complicado docker run imagen:version-anterior

Esta diferencia es especialmente valiosa en empresas como Bimbo, donde los equipos de tecnología están distribuidos en múltiples países y todos necesitan el mismo entorno de desarrollo.

Cómo aplicar esto hoy

  1. Toma cualquier script de Python o Node.js que ya tengas.
  2. Crea un Dockerfile usando las cinco instrucciones que aprendiste.
  3. Construye la imagen con docker build -t mi-app:1.0 .
  4. Corre un contenedor con docker run -p puerto:puerto mi-app:1.0.
  5. Verifica que funcione igual que en tu máquina local.

No necesitas un proyecto complejo para practicar. Un script que calcule el ISR de un salario de $18,500 ya es suficiente para aprender el flujo completo.

El Dockerfile convierte tu aplicación en un artefacto reproducible: escríbelo una vez y ejecútalo en cualquier lugar, en cualquier momento, con exactamente los mismos resultados.

Puntos clave

  • Un Dockerfile es una receta de texto que le dice a Docker cómo construir tu imagen. El sistema RECETA-IMAGEN garantiza reproducibilidad total.
  • Las cinco instrucciones esenciales son FROM, WORKDIR, COPY, RUN y CMD. Con ellas puedes empaquetar el 90% de las aplicaciones reales.
  • Siempre copia primero `requirements.txt` y luego instala dependencias antes de copiar el resto del código. Así Docker reutiliza capas en caché y tus builds son más rápidos.
  • Crea siempre un archivo `.dockerignore` para excluir carpetas como `.git`, `venv/` y archivos `.env`. Tu imagen queda más ligera y más segura.
  • Nunca uses `FROM imagen:latest` en producción. Fija la versión exacta (por ejemplo `python:3.11-slim`) para evitar que tu imagen se rompa cuando la base cambie.

Comparte esta lección: