Saltar a contenido

🐳 Docker y Docker Compose

Instalación y configuración de Docker para contenedores de aplicaciones.


Índice


Instalación de Docker

Instalar Docker y Docker Compose

sudo apt install docker.io docker-compose -y
sudo usermod -aG docker your_username

Importante: Cerrar sesión y volver a entrar para que el grupo docker se aplique:

exit
ssh your_username@YOUR_SERVER_IP

Verificar instalación

docker --version          # Docker version 28.2.2
docker-compose --version  # docker-compose version 1.29.2
docker ps                 # Debe funcionar sin errores de permisos

Resultado esperado:

Docker version 28.2.2, build 28.2.2-0ubuntu1~24.04.1
docker-compose version 1.29.2, build unknown
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Actualizar a Docker Compose v2

¿Por qué actualizar?

  • Docker Compose v1 (docker-compose): Versión legacy, ya no recibe actualizaciones importantes
  • Docker Compose v2 (docker compose): Plugin oficial, más rápido y mejor mantenido

Instalación del plugin v2

Como instalamos Docker desde repositorios de Ubuntu (docker.io), el plugin no está disponible en los repos. Lo instalamos manualmente:

# Crear directorio para plugins
sudo mkdir -p /usr/local/lib/docker/cli-plugins

# Descargar Docker Compose v2 (última versión)
sudo curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 \
  -o /usr/local/lib/docker/cli-plugins/docker-compose

# Dar permisos de ejecución
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose

# Verificar versión
docker compose version

Resultado esperado:

Docker Compose version v2.40.1

Ahora tienes ambas versiones

  • docker-compose (v1.29.2 - legacy) - Sigue funcionando
  • docker compose (v2.40.1 - nuevo) - ← Usa este de ahora en adelante

La sintaxis es casi idéntica, solo cambia el guión por espacio:

# Versión 1 (legacy)
docker-compose up -d

# Versión 2 (moderna) - RECOMENDADA
docker compose up -d

Configurar Memoria Swap

¿Por qué configurar Swap?

Con 4GB de RAM, la memoria swap es muy recomendable: - ✅ Evita que el sistema se bloquee si se queda sin memoria - ✅ Funciona como "colchón de seguridad" - ✅ Permite manejar picos temporales de uso - ✅ Previene que Docker mate procesos (OOM killer)

Crear archivo swap de 2GB

# Crear archivo swap
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# Hacer permanente (sobrevive reinicios)
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# Ajustar swappiness (usar swap solo cuando sea necesario)
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

¿Qué hace swappiness=10?

  • Valor por defecto: 60 (usa swap frecuentemente)
  • Valor 10: Solo usa swap cuando la RAM está casi llena
  • Ventaja: Mejor para SSDs porque reduce escrituras

Verificar que funciona

# Ver swap activa
free -h

# Ver información detallada de swap
swapon --show

# Ver swappiness configurado
cat /proc/sys/vm/swappiness
# Resultado esperado: debería mostrar "10"

Ejemplo de salida de free -h:

              total        used        free      shared  buff/cache   available
Mem:           3.8Gi       1.2Gi       1.5Gi        10Mi       1.1Gi       2.4Gi
Swap:          2.0Gi          0B       2.0Gi

Prueba de Funcionamiento

Desplegar un contenedor de prueba

# Crear directorio de prueba
mkdir -p ~/apps/compose-test && cd ~/apps/compose-test

# Crear docker-compose.yml
cat > docker-compose.yml <<'YAML'
services:
  hello:
    image: nginxdemos/hello
    ports: ["3000:80"]
YAML

# Levantar el servicio
docker compose up -d

# Ver contenedores
docker ps

Configurar Firewall para pruebas

IMPORTANTE: Para acceder a puertos personalizados (como 3000), debes abrirlos en AMBOS firewalls.

1. UFW (en el VPS):

sudo ufw allow 3000/tcp
sudo ufw status

2. Hetzner Cloud Firewall (desde el panel web): - Ve a Firewalls → Editar tu firewall - Añade regla Inbound: - Protocol: TCP - Port: 3000 - Source: Any IPv4/IPv6 - Guardar cambios

3. Probar:

Abre http://YOUR_SERVER_IP:3000 en tu navegador. Deberías ver una página de demo de Nginx.

Limpiar después de probar

cd ~/apps/compose-test

# Parar y eliminar contenedor
docker compose down

# Eliminar imagen (opcional)
docker rmi nginxdemos/hello

# Cerrar puerto en firewall (opcional)
sudo ufw delete allow 3000/tcp
# Y quitar la regla del puerto 3000 en Hetzner Cloud Firewall

Nota sobre Firewalls y Puertos Personalizados

Recuerda: Con doble firewall, AMBOS deben permitir el puerto:

  1. Hetzner Cloud Firewall filtra PRIMERO (capa externa)
  2. UFW filtra DESPUÉS (capa interna)

Si solo configuras uno, el tráfico será bloqueado.


Comandos Útiles

Docker básico

# Ver contenedores en ejecución
docker ps

# Ver todos los contenedores (incluidos detenidos)
docker ps -a

# Ver imágenes descargadas
docker images

# Ver logs de un contenedor
docker logs nombre_contenedor
docker logs -f nombre_contenedor  # seguir logs en tiempo real

# Ejecutar comando en contenedor
docker exec -it nombre_contenedor bash

# Ver uso de recursos en tiempo real
docker stats

# Ver redes de Docker
docker network ls

# Ver volúmenes de Docker
docker volume ls

# Limpiar recursos no usados (cuidado: elimina contenedores parados, imágenes no usadas, etc.)
docker system prune -a

# Ver información del sistema Docker
docker info

# Inspeccionar contenedor
docker inspect nombre_contenedor

# Parar todos los contenedores
docker stop $(docker ps -q)

# Eliminar todos los contenedores parados
docker container prune

Docker Compose v2 (Recomendado)

# Ver versión
docker compose version

# Levantar servicios en segundo plano
docker compose up -d

# Levantar servicios con rebuild
docker compose up -d --build

# Ver logs
docker compose logs
docker compose logs -f         # seguir logs
docker compose logs servicio   # logs de un servicio específico

# Parar servicios (mantiene contenedores)
docker compose stop

# Parar y eliminar contenedores
docker compose down

# Parar, eliminar contenedores y volúmenes
docker compose down -v

# Ver estado de servicios
docker compose ps

# Reiniciar servicios
docker compose restart

# Reiniciar un servicio específico
docker compose restart nombre_servicio

# Ejecutar comando en un servicio
docker compose exec nombre_servicio bash

# Ver configuración parseada
docker compose config

# Actualizar imagen y recrear
docker compose pull
docker compose up -d

# Escalar servicios
docker compose up -d --scale web=3

Docker Compose v1 (Legacy)

# Los comandos son los mismos, solo cambia el guion
docker-compose up -d
docker-compose down
docker-compose logs -f
# etc.

Recomendación: Usa docker compose (v2) para nuevos proyectos.

Gestión de memoria

# Ver uso de memoria y swap
free -h

# Ver procesos que consumen más memoria
ps aux --sort=-%mem | head -n 10

# Ver si el swap está activo
swapon --show

# Ver swappiness (debe ser 10)
cat /proc/sys/vm/swappiness

# Ver uso de recursos en tiempo real
htop

# Deshabilitar swap temporalmente (no recomendado)
sudo swapoff -a

# Habilitar swap
sudo swapon -a

Buenas Prácticas

Estructura de proyectos

~/apps/
├── nombre-app-1/
   ├── docker-compose.yml
   ├── .env
   └── data/
├── nombre-app-2/
   ├── docker-compose.yml
   └── config/
└── nombre-app-3/
    └── docker-compose.yml

Usar .env para configuraciones

# docker-compose.yml
services:
  web:
    image: nginx:alpine
    ports:
      - "${PORT}:80"
    environment:
      - DOMAIN=${DOMAIN}
# .env
PORT=3000
DOMAIN=ejemplo.com

Siempre usar restart policies

services:
  web:
    image: nginx:alpine
    restart: unless-stopped  # Reinicia automáticamente

Opciones de restart: - no: No reiniciar (default) - always: Siempre reiniciar - on-failure: Solo si falla - unless-stopped: Reiniciar excepto si se paró manualmente

Usar volúmenes nombrados

services:
  db:
    image: postgres:15
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Limpieza regular

# Limpiar imágenes no usadas (semanal/mensual)
docker image prune -a

# Limpiar volúmenes huérfanos
docker volume prune

# Limpieza completa (cuidado)
docker system prune -a --volumes

Recursos del Sistema

Especificaciones del VPS

  • RAM: 4 GB
  • Swap: 2 GB (configurado)
  • Disco: 40 GB NVMe
  • CPU: 2 vCPU

Monitoreo recomendado

# Revisar uso de memoria regularmente
free -h

# Ver uso de disco
df -h

# Ver uso de Docker
docker system df

# Estadísticas de contenedores
docker stats --no-stream

Troubleshooting

Docker no funciona después de instalarlo

# Cerrar sesión y volver a entrar
exit
ssh your_username@YOUR_SERVER_IP

# Verificar que estás en el grupo docker
groups

# Si no aparece "docker", vuelve a ejecutar:
sudo usermod -aG docker your_username

Error "permission denied" al usar Docker

# Verificar grupo docker
groups

# Si no estás en el grupo, añadirte:
sudo usermod -aG docker $USER

# Cerrar sesión y volver a entrar
exit
ssh your_username@YOUR_SERVER_IP

Contenedor no arranca

# Ver logs del contenedor
docker logs nombre_contenedor

# Ver eventos de Docker
docker events

# Inspeccionar contenedor
docker inspect nombre_contenedor

Sistema sin memoria

# Ver uso de memoria
free -h

# Ver swap activo
swapon --show

# Ver procesos que consumen memoria
docker stats

# Si es necesario, reiniciar contenedores
docker compose restart

⬅️ Anterior: Seguridad | Volver al índice | ➡️ Siguiente: Nginx