ejemplos-practicos-dockerfile

Ejemplos prácticos de Dockerfile

  • 5 min

Docker es una herramienta muy útil, pero enfrentarse a un archivo en blanco la primera vez puede intimidar. Afortunadamente, una de las ventajas es que no tienes que reinventar la rueda cada vez que inicias un proyecto.

En este artículo, he recopilado 10 ejemplos prácticos de Dockerfiles que cubren desde configuraciones básicas del sistema hasta arquitecturas avanzadas Multi-stage para lenguajes compilados.

Úsalos como plantillas base, cópialos y adáptalos a las necesidades de tus propios proyectos 👇.

Utilidades y configuración básica

Ideal para crear herramientas de línea de comandos aisladas o entender cómo funcionan las variables de entorno.

Imagen base (Ubuntu + Curl)

Este ejemplo ilustra cómo partir de un sistema operativo en blanco e instalar paquetes básicos de Linux.

FROM ubuntu:22.04

# Actualiza repositorios e instala curl
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

# Comando por defecto
CMD ["curl", "--version"]
Copied!

Uso de variables de entorno (httpie)

Aprende a usar la instrucción ENV para que tu contenedor sea dinámico y acepte parámetros al arrancar (ej: docker run -e URL=[https://google.com](https://google.com) mi-imagen).

FROM ubuntu:22.04

RUN apt-get update && apt-get install -y httpie && rm -rf /var/lib/apt/lists/*

# Definimos una variable con valor por defecto
ENV URL=https://example.com

# Usamos la variable en la ejecución
CMD ["sh", "-c", "http -h $URL"]
Copied!

Lenguajes interpretado

Las aplicaciones web clásicas suelen requerir copiar dependencias, instalarlas y luego copiar el código fuente.

Node.js (Express / Frontend)

El estándar de la industria para aplicaciones JavaScript. Copiamos el package.json antes que el código para aprovechar la caché de Docker.

FROM node:18-alpine
WORKDIR /app

# Instalamos dependencias primero
COPY package*.json ./
RUN npm install

# Copiamos el resto del código
COPY . .

EXPOSE 3000
CMD ["npm", "start"]
Copied!

Python (Django / Flask)

Preparado para instalar dependencias desde un archivo requirements.txt sin guardar caché basura que engorde la imagen.

FROM python:3.9-slim
WORKDIR /app

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

COPY . .

EXPOSE 8000
CMD ["python", "app.py"]
Copied!

PHP con Apache

Una configuración rapidísima para servir proyectos legacy o arquitecturas clásicas en PHP.

FROM php:8.1-apache

# Habilitamos mod_rewrite para URLs amigables
RUN a2enmod rewrite

# Copiamos el código directamente a la carpeta pública de Apache
COPY src/ /var/www/html/

# Ajustamos permisos
RUN chown -R www-data:www-data /var/www/html

EXPOSE 80
# El CMD ya viene configurado en la imagen base de Apache
Copied!

Ruby on Rails

Un entorno más complejo que requiere precompilar assets y gestionar herramientas del sistema antes de arrancar.

FROM ruby:3.2-slim
WORKDIR /app

# Instalamos dependencias del sistema necesarias para Rails
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

COPY Gemfile Gemfile.lock ./
RUN bundle install

COPY . .

# Precompilamos assets de Rails
RUN bundle exec rake assets:precompile

EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
Copied!

Lenguajes compilados

En lenguajes como Java, Go o .NET, usamos una imagen pesada para compilar el código, y luego copiamos solo el ejecutable final a una imagen vacía y ultra ligera para producción.

.NET (C# / ASP.NET)

La forma recomendada por Microsoft para empaquetar aplicaciones empresariales.

# ETAPA 1: Compilación y Publicación
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /source
COPY *.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish

# ETAPA 2: Producción (Solo Runtime)
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS runtime
WORKDIR /app
COPY --from=build /app/publish .

EXPOSE 80
ENTRYPOINT ["dotnet", "tu-aplicacion.dll"]
Copied!

Java (Spring Boot con Maven)

Compilamos el archivo .jar usando Maven en la primera etapa y lo ejecutamos usando un entorno Java ligero (JRE) en la segunda.

# ETAPA 1: Compilación
FROM maven:3.8-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests

# ETAPA 2: Producción
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar

EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
Copied!

Go (Golang)

Pasamos de una imagen de compilación de varios cientos de megas, a una imagen final de producción que ocupa apenas unos pocos MB.

# ETAPA 1: Compilación
FROM golang:1.20-alpine AS build
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o main_app

# ETAPA 2: Producción
FROM alpine:latest
WORKDIR /app
# Solo copiamos el binario compilado
COPY --from=build /app/main_app .

EXPOSE 8080
CMD ["./main_app"]
Copied!

Rust

Útil para microservicios de alto rendimiento donde la imagen final debe ser mínima y segura (it’s safe!! 🦀).

# ETAPA 1: Compilación
FROM rust:1.70 AS build
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
# Truco para cachear dependencias compilando un proyecto vacío
RUN mkdir src && echo "fn main() {}" > src/main.rs
RUN cargo build --release
RUN rm -rf src
# Compilamos el código real
COPY src ./src
RUN cargo build --release

# ETAPA 2: Producción
FROM debian:bullseye-slim
WORKDIR /app
COPY --from=build /app/target/release/mi_app /usr/local/bin/

EXPOSE 8000
CMD ["mi_app"]
Copied!