Manual Completo de Docker y Docker Compose

1. Introducción a Docker

Docker es una plataforma de código abierto para desarrollar, enviar y ejecutar aplicaciones en contenedores. Los contenedores permiten empaquetar una aplicación con todas sus dependencias en una unidad estandarizada para el desarrollo.

1.1 Conceptos básicos

Nota: Docker utiliza una arquitectura cliente-servidor. El daemon de Docker (dockerd) maneja las operaciones, mientras que el cliente Docker (docker) es la interfaz que usamos.

2. Instalación de Docker

2.1 Instalación en Linux (Ubuntu/Debian)

# Actualizar paquetes existentes
sudo apt update

# Instalar dependencias
sudo apt install apt-transport-https ca-certificates curl software-properties-common

# Agregar la clave GPG oficial de Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Agregar el repositorio de Docker
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Instalar Docker Engine
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

# Verificar instalación
sudo docker run hello-world

2.2 Instalación en Windows/macOS

Descargar Docker Desktop desde https://www.docker.com/products/docker-desktop y seguir el asistente de instalación.

2.3 Configuración post-instalación

# Agregar usuario actual al grupo docker para evitar usar sudo
sudo usermod -aG docker $USER

# Reiniciar sesión para aplicar cambios
newgrp docker

# Verificar que funciona sin sudo
docker run hello-world

3. Comandos básicos de Docker

3.1 Manejo de contenedores

Comando Descripción
docker run [imagen] Crear y ejecutar un contenedor
docker ps Listar contenedores en ejecución
docker ps -a Listar todos los contenedores
docker stop [contenedor] Detener un contenedor
docker start [contenedor] Iniciar un contenedor detenido
docker rm [contenedor] Eliminar un contenedor
docker logs [contenedor] Mostrar logs de un contenedor

3.2 Manejo de imágenes

Comando Descripción
docker images Listar imágenes locales
docker pull [imagen] Descargar una imagen
docker rmi [imagen] Eliminar una imagen
docker build -t [nombre] . Construir una imagen desde Dockerfile

3.3 Ejemplos prácticos

# Ejecutar un contenedor Nginx
docker run -d -p 8080:80 --name mi-nginx nginx

# Ejecutar un contenedor interactivo de Ubuntu
docker run -it ubuntu bash

# Eliminar todos los contenedores detenidos
docker container prune

# Eliminar todas las imágenes no utilizadas
docker image prune -a

4. Creación de imágenes con Dockerfile

Un Dockerfile es un documento de texto que contiene todos los comandos necesarios para construir una imagen.

4.1 Estructura básica

# Especificar la imagen base
FROM ubuntu:20.04

# Establecer el directorio de trabajo
WORKDIR /app

# Copiar archivos necesarios
COPY . .

# Instalar dependencias
RUN apt update && apt install -y python3 python3-pip

# Instalar dependencias de Python
RUN pip install -r requirements.txt

# Exponer puertos
EXPOSE 5000

# Comando a ejecutar al iniciar el contenedor
CMD ["python3", "app.py"]

4.2 Instrucciones más comunes

Instrucción Descripción
FROM Especifica la imagen base
RUN Ejecuta comandos durante la construcción
COPY Copia archivos del host al contenedor
ADD Similar a COPY pero con más funcionalidades
CMD Comando por defecto al iniciar el contenedor
ENTRYPOINT Configura el ejecutable del contenedor
ENV Establece variables de entorno
ARG Define variables para la construcción
EXPOSE Documenta los puertos a exponer
VOLUME Crea un punto de montaje

4.3 Buenas prácticas

Nota: Cada instrucción en un Dockerfile crea una nueva capa en la imagen. Es importante optimizar este proceso para reducir el tamaño final.

5. Volúmenes y Redes en Docker

5.1 Manejo de volúmenes

Los volúmenes son el mecanismo preferido para persistir datos generados por contenedores.

# Crear un volumen
docker volume create mi-volumen

# Listar volúmenes
docker volume ls

# Inspeccionar un volumen
docker volume inspect mi-volumen

# Usar un volumen en un contenedor
docker run -d -v mi-volumen:/datos --name contenedor-con-datos nginx

# Montar un directorio del host
docker run -d -v /ruta/local:/datos --name contenedor-con-datos nginx

5.2 Redes en Docker

Docker proporciona diferentes tipos de redes para conectar contenedores:

# Listar redes disponibles
docker network ls

# Crear una red personalizada
docker network create mi-red

# Conectar un contenedor a una red
docker run -d --network mi-red --name contenedor-en-red nginx

# Conectar múltiples contenedores
docker run -d --network mi-red --name contenedor1 nginx
docker run -d --network mi-red --name contenedor2 nginx

6. Docker Compose

Docker Compose es una herramienta para definir y ejecutar aplicaciones Docker multi-contenedor.

6.1 Estructura básica de docker-compose.yml

version: '3.8'

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
    depends_on:
      - db
  
  db:
    image: postgres:13
    environment:
      POSTGRES_PASSWORD: ejemplo
    volumes:
      - db_data:/var/lib/postgresql/data

volumes:
  db_data:

6.2 Comandos básicos

Comando Descripción
docker-compose up Crear e iniciar contenedores
docker-compose up -d Ejecutar en segundo plano
docker-compose down Detener y eliminar contenedores
docker-compose build Construir imágenes
docker-compose logs Mostrar logs
docker-compose ps Listar contenedores

6.3 Configuración avanzada

version: '3.8'

services:
  app:
    build: 
      context: .
      dockerfile: Dockerfile.prod
      args:
        NODE_ENV: production
    ports:
      - "3000:3000"
    environment:
      - DB_HOST=db
      - DB_PORT=5432
    depends_on:
      - db
      - redis
  
  db:
    image: postgres:13
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5
  
  redis:
    image: redis:6
    command: redis-server --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

Nota: Docker Compose permite usar variables de entorno desde un archivo .env o del sistema.

7. Casos prácticos

7.1 Aplicación web con Node.js y MongoDB

Dockerfile:

FROM node:14

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD ["node", "server.js"]

docker-compose.yml:

version: '3.8'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - MONGO_URL=mongodb://db:27017/mydb
    depends_on:
      - db
  
  db:
    image: mongo:4.4
    volumes:
      - mongo_data:/data/db

volumes:
  mongo_data:

7.2 Aplicación Python (Django) con PostgreSQL

Dockerfile:

FROM python:3.9

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

WORKDIR /code

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

docker-compose.yml:

version: '3.8'

services:
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    environment:
      - POSTGRES_NAME=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    depends_on:
      - db
  
  db:
    image: postgres:13
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

8. Mejores prácticas y seguridad

8.1 Seguridad en Docker

8.2 Optimización de imágenes

8.3 Multi-stage builds

# Fase de construcción
FROM node:14 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Fase de producción
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

9. Monitoreo y administración

9.1 Comandos útiles

# Ver uso de recursos
docker stats

# Ver procesos en un contenedor
docker top [contenedor]

# Ver cambios en el sistema de archivos
docker diff [contenedor]

# Inspeccionar metadatos
docker inspect [contenedor|imagen]

# Ver consumo de disco
docker system df

9.2 Herramientas de monitoreo

9.3 Ejemplo con Portainer

# Ejecutar Portainer
docker volume create portainer_data
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer \
    --restart=always \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v portainer_data:/data \
    portainer/portainer-ce

10. Conclusión

Docker y Docker Compose son herramientas esenciales para el desarrollo moderno, permitiendo crear entornos consistentes y reproducibles. Este manual cubre los conceptos fundamentales, pero Docker es un ecosistema extenso con muchas más características como: