Cuatro minutos por una línea cambiada
Un equipo cambia una línea del código de una tienda. La construcción tarda cuatro minutos, porque descarga otra vez todas las librerías.
Otro equipo cambia la misma línea y espera un segundo. Los dos escribieron un archivo de construcción. Escribieron los pasos en distinto orden.
Al terminar esta lección
Nota
Puedo escribir un Dockerfile y decir qué pasos se repiten tras un cambio.
Palabras clave
| Palabra | Qué significa |
|---|---|
| Dockerfile | un archivo de texto con pasos que construye una imagen |
| Imagen base | la imagen de la que parte una construcción |
| Capa (layer) | el resultado guardado de un paso de construcción |
| Caché | capas guardadas que una construcción reutiliza |
| Construir (build) | hacer una imagen ejecutando los pasos |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Lo que el laboratorio no puede hacer
Nota
El docker del laboratorio rechaza construir o descargar una imagen: una construcción ejecuta pasos con derechos sobre la máquina. Construimos estos Dockerfile en nuestra máquina. Tú los lees, miras lo que una imagen deja en un contenedor y compruebas tu propio archivo en el trabajo. Para construir de verdad, usa tu máquina.
Un Dockerfile es una lista de pasos
Cada línea empieza con una palabra de instrucción. FROM nombra la imagen base. COPY trae archivos. RUN ejecuta un comando mientras se construye. CMD dice qué ejecutar cuando arranca un contenedor.
Docker lee las líneas desde arriba. Aquí tienes una tienda pequeña escrita así.
Un Dockerfile para una tienda pequeña en Python
FROM python:3.12-alpine
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
CMD ["python", "app.py"]
La carpeta de inicio, fijada por WORKDIR
docker inspect --format '{{.Config.WorkingDir}}' cacheSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
La señal que para web, fijada por STOPSIGNAL
docker inspect --format '{{.Config.StopSignal}}' webSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejemplo resuelto: lo que deja cada instrucción
| Instrucción | Qué hace al construir | Dónde se ve después |
|---|---|---|
| FROM | parte de una imagen base | Config.Image nombra la imagen |
| WORKDIR | fija la carpeta de los pasos siguientes | Config.WorkingDir, /data en cache |
| EXPOSE | dice qué puerta usa el programa | Config.ExposedPorts, 80/tcp en web |
| STOPSIGNAL | dice cómo pedir al programa que pare | Config.StopSignal, SIGQUIT en web |
| COPY y RUN | añaden archivos y ejecutan comandos | una capa nueva cada uno |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Cada paso hace una capa
Una construcción guarda el resultado de cada paso como una capa. Las capas se apilan, y una imagen es toda la pila. Una capa no cambia una vez hecha.
Un contenedor añade una capa fina encima, donde escribe. docker diff lista lo que hay en esa capa de arriba.
Ejemplo resuelto: las capas de la imagen
| Paso | Tamaño en nuestra máquina de prueba |
|---|---|
| La imagen base, python:3.12-alpine | unos 48 MB su capa más grande |
| WORKDIR /app | 8 kB |
| COPY requirements.txt . | 12 kB |
| RUN pip install ... | 10,6 MB |
| COPY app.py . | 12 kB |
| CMD ["python", "app.py"] | 0 B |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Escribe un archivo en web
docker exec web touch /tmp/layer-demo.txtSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Encuéntralo en la capa de arriba
docker diff web | grep layer-demoSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Una capa se reutiliza si nada cambia
Antes de ejecutar un paso, Docker se hace una pregunta. ¿Es el mismo paso, con los mismos archivos que la última vez, y era igual todo lo de arriba? Si es así, reutiliza la capa guardada. Es la caché.
El primer paso que difiere se repite. También todos los siguientes. Pon arriba lo que menos cambia.
Orden 1: copiar todo primero
FROM python:3.12-alpine
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir -r requirements.txt
CMD ["python", "app.py"]
Ejemplo resuelto: editar app.py y reconstruir
| Paso | Orden 1 | Orden 2 (el primer Dockerfile de arriba) |
|---|---|---|
| WORKDIR /app | en caché | en caché |
| COPY requirements.txt . | no está en este orden | en caché |
| COPY . . | se repite | no está en este orden |
| RUN pip install ... | se repite, 11 segundos | en caché |
| COPY app.py . | no está en este orden | se repite, menos de un segundo |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Un error frecuente
Advertencia
Mucha gente cree que Docker repite solo la línea que editó. Repite ese paso y todos los que vienen después. Copia primero el archivo que lista tus librerías e instálalas, y luego copia tu propio código. El paso lento se queda en caché.
Para ir más lejos
Escribe el Dockerfile de un sitio pequeño tuyo. Parte de nginx:1.27-alpine, copia un solo index.html en /usr/share/nginx/html y no añadas nada más.
En una máquina con Docker, constrúyelo dos veces. La segunda construcción debe mostrar CACHED en cada paso.