Docker fundamentos
Docker permite crear, desplegar y ejecutar aplicaciones en contenedores—aíslados del sistema operativo. Cada contenedor tiene su propio sistema de archivos, librerías, y dependencias.
Conceptos básicos
Imagen vs Contenedor
- Imagen: plantilla read-only para crear contenedores. Como una clase en OOP.
- Contenedor: instancia ejecutándose de una imagen. Como un objeto en OOP.
Registry
Lugar donde se almacenan imágenes Docker. El más común es Docker Hub (docker.io). Puedes usar otros (Google Container Registry, GitHub Packages, etc.).
Comandos esenciales
Imágenes
docker images # Ver imágenes descargadas
docker pull ubuntu:22.04 # Descargar imagen
docker rmi ubuntu:22.04 # Eliminar imagenContenedores
docker ps # Contenedores ejecutándose
docker ps -a # Todos los contenedores (incluidos parados)
docker run -it ubuntu:22.04 # Crear y ejecutar contenedor interactivo
docker start mi-contenedor # Iniciar contenedor parado
docker stop mi-contenedor # Parar contenedor
docker rm mi-contenedor # Eliminar contenedorflags comunes
docker run -d # Modo detached (en segundo plano)
docker run -p 8080:80 # Mapear puerto host:contenedor
docker run -v /data:/data # Montar volumen host:contenedor
docker run --name mi-app # Nombrar el contenedorDockerfile
Archivo de instrucciones para construir una imagen.
Ejemplo: Videogames API (Java 21)
# Usar imagen oficial de Java con Alpine (ligero)
FROM eclipse-temurin:21-jdk-alpine
# Directorio de trabajo
WORKDIR /app
# Copiar el JAR compilado
COPY target/*.jar app.jar
# Exponer puerto
EXPOSE 8080
# Comando inicial
ENTRYPOINT ["java", "-jar", "app.jar"]Ejemplo: FastAPI (Python)
FROM python:3.12-slim
WORKDIR /app
# Copiar requirements primero (mejor caché)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copiar código
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]Buenas prácticas
Orden de capas importa: Docker reconstruye desde la capa que cambió. Copiar requirements.txt antes que el código permite caché:
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . . # Este cambio no invalida el caché de pipUsar imágenes oficiales pequeñas: alpine vs ubuntu vs debian.
Docker Compose
Para aplicaciones con múltiples contenedores (ej: app + base de datos).
# docker-compose.yml
version: '3.8'
services:
api:
build: .
ports:
- "8080:8080"
environment:
- DATABASE_URL=postgresql://db:5432/mydb
depends_on:
- db
db:
image: postgres:15-alpine
environment:
- POSTGRES_DB=mydb
- POSTGRES_USER=user
- POSTGRES_PASSWORD=secret
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:docker-compose up -d # Crear e iniciar
docker-compose down # Parar y eliminar
docker-compose logs # Ver logs
docker-compose exec db psql -U user -d mydb # Conectar a DBConcepto de capas
Cada instrucción en Dockerfile crea una capa (layer):
FROM ubuntu:22.04 # Capa 1: imagen base
RUN apt-get update # Capa 2
RUN apt-get install -y git # Capa 3
COPY . /app # Capa 4Docker reutiliza capas entre imágenes si no cambiaron. Por eso copiar requirements.txt antes que el código fuente aprovecha el caché.
Desarrollo local con Docker
Mi flujo para proyectos Python/Flask
# 1. Crear Dockerfile en backend/
# 2. docker-compose.yml
# 3. Levantar
docker-compose up --build
# 4. Ver logs
docker-compose logs -f backend
# 5. Debug: entrar al contenedor
docker-compose exec backend bashVolúmenes para desarrollo
services:
backend:
build: .
volumes:
- ./backend:/app # Sincroniza cambios en tiempo real
command: uvicorn main:app --reload --host 0.0.0.0 --port 8000Con --reload, Flask recarga cuando cambias el código.
Ejemplo real: Videogames API en Railway
Railway puede desplegar desde un Dockerfile:
FROM eclipse-temurin:21-jdk-alpine
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]Railway detecta el Dockerfile, construye la imagen, y despliega el contenedor.
Comandos de limpieza
docker system prune # Eliminar todo lo no usado
docker image prune -a # Eliminar imágenes sin usar
docker container prune # Eliminar contenedores paradosCuándo usar Docker
Sí:
- Desplegar en producción ( Railway, Render, Fly.io)
- Entorno de desarrollo consistente (todos usan la misma imagen)
- Microservicios (base de datos separada de la app)
- CI/CD (mismo entorno en pipeline que en producción)
No:
- Proyecto simple de una sola página → overkill
- Cuando el hosting no lo soporta (GitHub Pages no tiene Docker)
Docker parece complicado al principio, pero su modelo es simple: imágenes capas, contenedores instancias, compose multi-contenedor. Una vez que lo internalizas, desplegar deja de dar miedo.
Más guías y proyectos en mmoreno.dev.