Guía Completa de Dockerfile
Índice
Introducción
Un Dockerfile es un archivo de texto que contiene las instrucciones necesarias para construir una imagen de Docker. Cada instrucción en el Dockerfile crea una nueva capa en la imagen.
Sintaxis Básica
# Comentario
INSTRUCCIÓN argumentos
- Las instrucciones no son sensibles a mayúsculas, pero por convención se escriben en mayúsculas
- Cada instrucción crea una nueva capa en la imagen
- Los comentarios comienzan con
#
Instrucciones Principales
FROM
Define la imagen base.
| FROM <imagen>:<tag>
FROM ubuntu:20.04
FROM node:14-alpine
|
LABEL
Agrega metadatos a la imagen.
| LABEL version="1.0"
LABEL descripcion="Mi aplicación"
LABEL mantenedor="nombre@email.com"
|
ENV
Define variables de entorno.
| ENV APP_HOME=/usr/src/app
ENV PORT=3000
|
ARG
Define variables para el proceso de construcción.
| ARG VERSION=latest
ARG BUILD_DATE
|
WORKDIR
Establece el directorio de trabajo.
| WORKDIR /app
WORKDIR $APP_HOME
|
COPY
Copia archivos desde el host a la imagen.
| COPY archivo.txt /app/
COPY ["archivo con espacios.txt", "/app/"]
COPY . .
|
ADD
Similar a COPY, pero con funcionalidades adicionales.
| ADD archivo.tar.gz /app/
ADD https://ejemplo.com/archivo.zip /app/
|
RUN
Ejecuta comandos durante la construcción.
| RUN apt-get update && \
apt-get install -y nginx
RUN ["npm", "install"]
|
CMD
Define el comando por defecto al ejecutar el contenedor.
| CMD ["nginx", "-g", "daemon off;"]
CMD ["npm", "start"]
CMD /script.sh
|
ENTRYPOINT
Define el ejecutable principal del contenedor.
| ENTRYPOINT ["nginx"]
ENTRYPOINT ["node", "app.js"]
|
EXPOSE
Documenta los puertos que escucha el contenedor.
| EXPOSE 80
EXPOSE 3000/tcp
EXPOSE 53/udp
|
VOLUME
Define puntos de montaje para volúmenes.
| VOLUME /data
VOLUME ["/data", "/logs"]
|
USER
Define el usuario para ejecutar comandos.
| USER nginx
USER 1000:1000
|
HEALTHCHECK
Define comando para verificar la salud del contenedor.
| HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost/ || exit 1
|
SHELL
Define el shell por defecto para comandos.
| SHELL ["/bin/bash", "-c"]
|
STOPSIGNAL
Define la señal para detener el contenedor.
Variables y Arguments
Variables de Entorno
| # Definición de variables
ENV APP_VERSION=1.0
ENV APP_PORT=3000
# Uso de variables
EXPOSE $APP_PORT
|
Build Arguments
| # Definición de argumentos
ARG BUILD_VERSION
ARG ENVIRONMENT=production
# Uso de argumentos
LABEL version=${BUILD_VERSION}
|
Buenas Prácticas
1. Optimización de Capas
| # Mal
RUN apt-get update
RUN apt-get install -y nginx
RUN apt-get clean
# Bien
RUN apt-get update && \
apt-get install -y nginx && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
|
2. Multi-stage Builds
| # Etapa de compilación
FROM node:14 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Etapa de producción
FROM node:14-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/main.js"]
|
3. Ordenamiento de Capas
| # Ordenar de menos a más frecuentemente cambiante
FROM node:14-alpine
# 1. Instalar dependencias del sistema
RUN apk add --no-cache python3
# 2. Instalar dependencias de la aplicación
COPY package*.json ./
RUN npm install
# 3. Copiar código fuente
COPY . .
|
4. Uso de .dockerignore
| # .dockerignore
node_modules
npm-debug.log
Dockerfile
.git
.gitignore
|
Ejemplos Prácticos
Aplicación Node.js
| FROM node:14-alpine
# Metadatos
LABEL version="1.0.0"
LABEL description="Aplicación Node.js de ejemplo"
# Variables de entorno
ENV NODE_ENV=production
ENV PORT=3000
# Directorio de trabajo
WORKDIR /usr/src/app
# Instalación de dependencias
COPY package*.json ./
RUN npm ci --only=production
# Código fuente
COPY . .
# Puerto
EXPOSE $PORT
# Comando de inicio
CMD ["node", "server.js"]
|
Aplicación Python con Django
| FROM python:3.9-slim
# Variables de entorno
ENV PYTHONUNBUFFERED=1
ENV DJANGO_SETTINGS_MODULE=myproject.settings
# Directorio de trabajo
WORKDIR /app
# Dependencias del sistema
RUN apt-get update && \
apt-get install -y --no-install-recommends \
gcc \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
# Dependencias Python
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Código fuente
COPY . .
# Puerto
EXPOSE 8000
# Comando de inicio
CMD ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:8000"]
|
Aplicación Java con Maven
| # Etapa de compilación
FROM maven:3.8-openjdk-11 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
# Etapa de producción
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
|
Variables Especiales
Variables Predefinidas
| ARG
- ${} # Referencia a variable
- $? # Código de salida del último comando
- $$ # PID del shell actual
|
Variables en Tiempo de Construcción
| ARG VERSION
ARG BUILD_DATE
ARG VCS_REF
LABEL org.label-schema.version=$VERSION
LABEL org.label-schema.build-date=$BUILD_DATE
LABEL org.label-schema.vcs-ref=$VCS_REF
|