8. Construir nuestras propias imágenes
Temas del programa: 4.1.2 y 4.1.3
De una imagen existente a una imagen propia
Section titled “De una imagen existente a una imagen propia”Hasta ahora utilizamos imágenes que otras personas construyeron
Registry │ ▼Imagen existente │ ▼ContenedorAhora construiremos una imagen para nuestra aplicación
Código │ ▼Dockerfile │ ▼Imagen propia │ ▼Contenedor¿Qué es un Dockerfile?
Section titled “¿Qué es un Dockerfile?”Un Dockerfile es un archivo de texto que describe instrucciones para construir una imagen de contenedor
Por ejemplo puede indicar
- Qué imagen se utilizará como base
- En qué directorio trabajar
- Qué archivos copiar
- Qué dependencias instalar
- Qué comando ejecutar al iniciar el contenedor
Dockerfile como receta
Section titled “Dockerfile como receta”RECETA
1. Seleccionar ingredientes2. Preparar los ingredientes3. Seguir instrucciones4. Obtener un resultadoDOCKERFILE
FROMWORKDIRCOPYRUNCMDCada instrucción tiene una función específica durante la construcción o ejecución
Primer ejemplo con PHP
Section titled “Primer ejemplo con PHP”Archivo hola.php
<?php
echo "Hola desde PHP en un contenedor" . PHP_EOL;Archivo Dockerfile
FROM php:8.3-cli
WORKDIR /app
COPY hola.php .
CMD ["php", "hola.php"]La imagen base incluye PHP CLI y el Dockerfile agrega nuestro archivo y define el comando predeterminado
¿Qué significa FROM?
Section titled “¿Qué significa FROM?”FROM php:8.3-cliIndica la imagen base de la que partirá la construcción
Imagen basephp:8.3-cli │ ▼Nuestra imagenLa imagen base ya contiene archivos y componentes necesarios para ejecutar PHP CLI
Conviene elegir una versión compatible con la aplicación y revisar su mantenimiento
¿Qué significa WORKDIR?
Section titled “¿Qué significa WORKDIR?”WORKDIR /appEstablece el directorio de trabajo para las instrucciones posteriores que lo utilicen
Contenedor
/├── usr├── etc└── app └── hola.phpDocker crea el directorio si es necesario durante la construcción
¿Qué significa COPY?
Section titled “¿Qué significa COPY?”COPY hola.php .Copia el archivo desde el contexto de construcción al directorio de trabajo de la imagen
Equipo de desarrollo │ │ COPY ▼Imagen/app/hola.phpLa ruta de origen se interpreta dentro del contexto de construcción
¿Qué significa RUN?
Section titled “¿Qué significa RUN?”RUN comandoEjecuta una instrucción durante la construcción de la imagen
Por ejemplo en una imagen basada en Debian o Ubuntu
RUN apt-get updateNo es un comando que se repita automáticamente cada vez que se inicia el contenedor
La sintaxis y los paquetes disponibles dependen de la imagen base
¿Qué significa CMD?
Section titled “¿Qué significa CMD?”CMD ["php", "hola.php"]Define el comando predeterminado que se ejecutará al iniciar el contenedor si no se proporciona otro comando que lo sustituya
Imagen │ ▼docker run │ ▼php hola.phpLa forma de lista JSON suele ser preferible para ejecutar directamente el programa y gestionar señales correctamente
RUN contra CMD
Section titled “RUN contra CMD”RUN | CMD |
|---|---|
| Se ejecuta durante la construcción | Define el comando o parámetros predeterminados de ejecución |
| Contribuye a construir la imagen | Se utiliza al iniciar el contenedor |
| Puede generar una capa de imagen | No genera por sí mismo una capa de archivos durante la construcción |
No deben utilizarse como si fueran instrucciones equivalentes
Construir la imagen
Section titled “Construir la imagen”Desde el directorio que contiene el Dockerfile y hola.php
docker build -t hola-php:1.0 .Significado
docker buildConstruye una imagen
-t hola-php:1.0Asigna nombre y etiqueta
.Utiliza el directorio actual como contextoLa construcción puede descargar la imagen base si no está disponible localmente
Ejecutar la imagen
Section titled “Ejecutar la imagen”docker run --rm hola-php:1.0Salida ilustrativa
Hola desde PHP en un contenedorEl comando inicia el proceso definido por CMD
Como se utiliza --rm el contenedor se elimina al terminar
La imagen hola-php:1.0 permanece disponible localmente
¿Qué es una etiqueta?
Section titled “¿Qué es una etiqueta?”Una etiqueta permite identificar una versión o variante de una imagen
hola-php:1.0hola-php:1.1hola-php:2.0No se debe asumir que una etiqueta garantiza por sí sola que el contenido nunca cambiará
Para identificar contenido de manera más precisa existen referencias por digest
¿Qué son las capas de una imagen?
Section titled “¿Qué son las capas de una imagen?”Las imágenes se construyen mediante capas y metadatos
┌─────────────────────────────┐│ Archivos de la aplicación │├─────────────────────────────┤│ Dependencias │├─────────────────────────────┤│ PHP │├─────────────────────────────┤│ Archivos de la imagen base │└─────────────────────────────┘Las capas permiten reutilizar contenido compartido y optimizar construcciones y descargas
¿Por qué importa el orden?
Section titled “¿Por qué importa el orden?”Si una instrucción cambia puede invalidarse parte de la caché de construcción
Menos eficiente para muchos proyectos
COPY . .RUN composer installUna alternativa común
COPY composer.json composer.lock ./RUN composer installCOPY . .Así los archivos de dependencias pueden aprovechar la caché cuando no cambian
La estrategia correcta depende del sistema de construcción y de la aplicación
¿Qué es .dockerignore?
Section titled “¿Qué es .dockerignore?”Es un archivo que indica qué rutas deben excluirse del contexto de construcción enviado a Docker
Ejemplo
.git.env.env.*node_modulesvendorstorage/logsLa lista debe adaptarse al proyecto
No conviene excluir archivos que sean necesarios para construir correctamente la imagen
¿Por qué es importante?
Section titled “¿Por qué es importante?”El contexto de construcción puede incluir
CódigoDependencias localesArchivos temporalesCredencialesHistorial GitRegistrosUn .dockerignore adecuado reduce archivos innecesarios y ayuda a evitar que información sensible se incorpore accidentalmente al contexto
No es un mecanismo suficiente para proteger secretos por sí solo
Configuración y secretos
Section titled “Configuración y secretos”CÓDIGO
app/routes/controllers/CONFIGURACIÓN
APP_ENVDB_HOSTDB_PORTSECRETOS
DB_PASSWORDAPI_KEYAPP_KEYLa configuración debe separarse del código siempre que sea posible
Los secretos no deben quedar incrustados en el Dockerfile ni en las capas de la imagen
Un Dockerfile problemático
Section titled “Un Dockerfile problemático”FROM php:latest
ENV DB_PASSWORD=ClaveReal
COPY . /var/www/html
RUN chmod -R 777 /var/www/html
CMD ["php", "-S", "0.0.0.0:8000"]Problemas que debemos reconocer
- La etiqueta
latestpuede cambiar - Se incorpora una contraseña a la imagen
- Se conceden permisos excesivos
- No se documentan claramente las dependencias
- El servidor integrado de PHP no debe asumirse apropiado para producción
Principios para mejorar una imagen
Section titled “Principios para mejorar una imagen”Elegir versiones compatibles y mantenerlas actualizadas
Incluir solo componentes necesarios
Ejecutar con la identidad adecuada
Las decisiones deben responder a los requisitos reales de la aplicación
¿Qué significa ejecutar como usuario no root?
Section titled “¿Qué significa ejecutar como usuario no root?”En Linux el usuario root tiene privilegios muy elevados
Cuando sea compatible con la aplicación podemos configurar un usuario específico
USER appEl usuario debe existir y tener permisos suficientes para ejecutar el programa y acceder a sus archivos
No se debe asumir que todas las imágenes incluyen un usuario llamado app
Multi-stage builds
Section titled “Multi-stage builds”Algunas aplicaciones necesitan herramientas para construir pero no para ejecutarse
Una construcción por etapas permite separar ambos entornos
Etapa de construcciónCompiladores y herramientas │ ▼Artefactos generados │ ▼Etapa de ejecuciónSolo componentes necesariosEsta técnica puede reducir el tamaño de la imagen final y la cantidad de herramientas disponibles en ejecución
Su implementación depende del lenguaje y del proceso de construcción
Relación con el laboratorio
Section titled “Relación con el laboratorio”Este tema se practica en el Laboratorio 2 — Tu sistema en una imagen: Dockerfile.
Qué sigue
Section titled “Qué sigue”Continúa con 9. Docker Compose.

