Docker ha transformado la forma de desplegar aplicaciones en servidores. Lo que antes tomaba horas de configurar (PHP + MySQL + Redis + ImageMagick + librerías exactas), hoy se levanta en 1 comando con un docker-compose.yml. Mejor aún: cada app vive aislada y no choca con otras.
En esta guía vamos a instalar Docker y Docker Compose en un VPS Ubuntu, paso a paso, y veremos 5 casos de uso reales para que entiendas para qué sirve y empieces a usarlo de inmediato.
¿Qué es Docker exactamente?
Docker es una plataforma de contenedores. Un contenedor es un paquete autosuficiente con:
- La app (tu código).
- Su sistema operativo mínimo (Alpine, Debian, Ubuntu).
- Sus dependencias (Python 3.12, Node 20, librerías).
- Su configuración.
Todo eso corre aislado del resto del sistema, en una versión exacta que tú defines. No importa si tu VPS usa Ubuntu 22 o 24, el contenedor lleva su entorno consigo.
Beneficios concretos
- Reproducibilidad: si funciona en tu laptop, funciona idéntico en el VPS.
- Aislamiento: un servicio mal configurado no afecta los demás.
- Actualización trivial: cambias una línea (
image: app:1.2 → 1.3) y actualizas. - Multi-versión: puedes correr PHP 7 y PHP 8 en el mismo VPS sin pelearse.
- Backup atómico: respalda volúmenes y archivos compose, listo.
- Despliegue en otros servidores: copias el
docker-compose.ymly todo se replica.
Docker no es una máquina virtual
Docker NO emula un OS completo (eso es lo que hace una VM como VirtualBox). Docker comparte el kernel del host y aísla procesos. Por eso es mucho más liviano y rápido: arranca en milisegundos, consume menos RAM y permite correr 20 contenedores en un VPS donde solo cabrían 2 VMs.
Requisitos
- VPS Ubuntu 22.04 LTS o 24.04 LTS (o Debian 12).
- 2 GB RAM mínimo (4 GB+ recomendado para correr varios contenedores).
- Acceso SSH con privilegios sudo.
- 20 GB de disco libre (las imágenes Docker pueden pesar varios GB).
Paso 1: Actualizar el sistema
sudo apt update && sudo apt upgrade -y
Paso 2: Desinstalar versiones viejas (si aplica)
sudo apt remove -y docker docker-engine docker.io containerd runc 2>/dev/null
(Si nunca instalaste Docker antes, simplemente verás un mensaje “no encontrado”.)
Paso 3: Instalar Docker desde el repo oficial
Hay 2 opciones: una rápida (script oficial) y una manual (más control).
Opción A: Script oficial (recomendado para principiantes)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
rm get-docker.sh
Esto instala la última versión estable de Docker y Docker Compose plugin.
Opción B: Instalación manual
# Instalar prerequisitos
sudo apt install -y ca-certificates curl gnupg
# Crear directorio de keys
sudo install -m 0755 -d /etc/apt/keyrings
# Importar la GPG key de Docker
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Añadir el repositorio
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo \"$VERSION_CODENAME\") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Actualizar e instalar
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Paso 4: Agregar tu usuario al grupo docker
Para no tener que escribir sudo antes de cada comando:
sudo usermod -aG docker $USER
Cierra sesión y vuelve a entrar para que el cambio aplique:
exit
ssh tu-usuario@tu-vps
Paso 5: Verificar la instalación
docker --version
docker compose version
Deberías ver algo como:
Docker version 25.0.3, build 4debf41
Docker Compose version v2.24.6
Ejecuta el “hello world”:
docker run --rm hello-world
Si ves el mensaje “Hello from Docker!”, estás listo.
Paso 6: Comandos básicos de Docker
Listar contenedores
docker ps # Solo los corriendo
docker ps -a # Todos (incluso parados)
Listar imágenes
docker images
Descargar una imagen
docker pull nginx:latest
Correr un contenedor
docker run -d --name mi-nginx -p 80:80 nginx
-d= detached (en background).--name= nombre del contenedor.-p 80:80= mapea puerto 80 del host al 80 del contenedor.
Ver logs
docker logs mi-nginx
docker logs -f mi-nginx # follow (live)
Entrar al contenedor
docker exec -it mi-nginx bash
Detener / arrancar / borrar
docker stop mi-nginx
docker start mi-nginx
docker restart mi-nginx
docker rm mi-nginx # borrar (debe estar parado)
docker rm -f mi-nginx # forzar borrado
Limpiar todo (cuidado)
docker system prune -a # Borra imágenes, contenedores y volúmenes no usados
Paso 7: Docker Compose para orquestar servicios
Docker Compose te permite declarar varios servicios juntos en un archivo docker-compose.yml:
version: '3.8'
services:
app:
image: nginx
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
Luego:
docker compose up -d # Arranca todos los servicios
docker compose down # Los detiene y elimina
docker compose ps # Estado actual
docker compose logs -f # Logs en vivo
docker compose pull && docker compose up -d # Actualizar imágenes
Caso de uso 1: WordPress + MySQL en 30 segundos
Crea ~/wordpress/docker-compose.yml:
version: '3.8'
services:
wordpress:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wp
WORDPRESS_DB_PASSWORD: claveSegura
WORDPRESS_DB_NAME: wp
volumes:
- wordpress_data:/var/www/html
depends_on:
- db
db:
image: mysql:8
environment:
MYSQL_DATABASE: wp
MYSQL_USER: wp
MYSQL_PASSWORD: claveSegura
MYSQL_ROOT_PASSWORD: clave-root-segura
volumes:
- db_data:/var/lib/mysql
volumes:
wordpress_data:
db_data:
cd ~/wordpress
docker compose up -d
En 30 segundos tienes WordPress completo corriendo en http://tu-ip:8080. Sin instalar PHP, sin configurar MySQL, sin nada.
Caso de uso 2: N8N para automatizaciones
Crea ~/n8n/docker-compose.yml:
version: '3.8'
services:
n8n:
image: docker.n8n.io/n8nio/n8n
restart: always
ports:
- "5678:5678"
environment:
- N8N_HOST=n8n.tudominio.com
- N8N_PROTOCOL=https
- GENERIC_TIMEZONE=America/Bogota
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=ClaveSegura123!
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:
Ver detalles completos en la guía de instalar N8N en VPS.
Caso de uso 3: PostgreSQL para tu app
version: '3.8'
services:
postgres:
image: postgres:16
restart: always
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: claveSegura
POSTGRES_DB: midatabase
ports:
- "127.0.0.1:5432:5432" # Solo accesible desde el host
volumes:
- pg_data:/var/lib/postgresql/data
volumes:
pg_data:
Conéctate desde otra app:
docker exec -it postgres-postgres-1 psql -U app -d midatabase
Caso de uso 4: Chatwoot (soporte cliente self-hosted)
Chatwoot es alternativa open-source a Intercom/Zendesk:
version: '3.8'
services:
chatwoot:
image: chatwoot/chatwoot:latest
restart: always
ports:
- "3000:3000"
environment:
RAILS_ENV: production
SECRET_KEY_BASE: cambia-esto-por-secret-largo
REDIS_URL: redis://redis:6379
POSTGRES_HOST: postgres
POSTGRES_USERNAME: chatwoot
POSTGRES_PASSWORD: chatwootPass
INSTALLATION_NAME: Mi Empresa
depends_on:
- redis
- postgres
redis:
image: redis:alpine
postgres:
image: postgres:14
environment:
POSTGRES_USER: chatwoot
POSTGRES_PASSWORD: chatwootPass
POSTGRES_DB: chatwoot
volumes:
- chatwoot_db:/var/lib/postgresql/data
volumes:
chatwoot_db:
Caso de uso 5: Múltiples sitios web con Nginx Proxy Manager
Si vas a correr varios sitios en el mismo VPS y quieres SSL automático + reverse proxy con UI:
version: '3.8'
services:
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
restart: always
ports:
- "80:80"
- "443:443"
- "81:81" # Panel admin
volumes:
- npm_data:/data
- npm_letsencrypt:/etc/letsencrypt
volumes:
npm_data:
npm_letsencrypt:
Entra a http://tu-vps:81 (login default: admin@example.com / changeme). Agrega tus dominios desde la UI, NPM configura Nginx y Let’s Encrypt automáticamente.
Mejores prácticas de seguridad con Docker
1. No expongas servicios al exterior si no es necesario
Usa 127.0.0.1:5432:5432 en lugar de 5432:5432 para servicios internos (BD, Redis). Solo lo accede el host.
2. Mantén las imágenes actualizadas
Mensualmente:
docker compose pull
docker compose down
docker compose up -d
3. Usa secretos en lugar de hardcodear contraseñas
Crea archivo .env:
DB_PASSWORD=claveSuperSegura
En docker-compose.yml:
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
Y agrega .env al .gitignore si versionas con Git.
4. Limita recursos por contenedor
services:
app:
image: nginx
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'
Evita que un contenedor descontrolado tumbe todo el VPS.
5. Configura logs con rotación
/etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Sin esto, los logs pueden crecer hasta llenar el disco.
6. Backup de volúmenes
docker run --rm -v wordpress_data:/data -v $(pwd):/backup alpine tar -czf /backup/wp-data.tar.gz /data
ServerAvatar: administra Docker (y más) sin línea de comandos
Si los comandos te abruman, ServerAvatar (incluido sin costo con VPS Moshipp) te da una interfaz gráfica para:
- Desplegar sitios web sin tocar Nginx.
- Gestionar bases de datos visualmente.
- Activar SSL con 1 click.
- Configurar backups programados.
- Monitorear recursos del VPS.
ServerAvatar no reemplaza Docker — es complementario. Puedes usar ServerAvatar para los sitios “tradicionales” y Docker para tus apps custom o servicios como N8N/Chatwoot.
Errores comunes con Docker
”Cannot connect to the Docker daemon”
Tu usuario no está en el grupo docker. Ejecuta:
sudo usermod -aG docker $USER
Y vuelve a iniciar sesión.
”Port is already allocated”
Otro servicio usa ese puerto. Cambia el puerto en el docker-compose.yml o detén el servicio rival:
sudo lsof -i :80
sudo systemctl stop nginx
“No space left on device”
Docker dejó imágenes y volúmenes acumulados:
docker system prune -a --volumes
df -h # Verifica espacio libre
“Container exits inmediately”
El proceso principal del contenedor murió. Revisa los logs:
docker logs nombre-contenedor
“Out of memory” en el host
Limita la RAM por contenedor (sección de mejores prácticas) o sube el plan del VPS.
Preguntas frecuentes
¿Docker hace mi VPS más lento?
Casi nada: el overhead de Docker es minimal (1-3% de CPU). Para cargas serias, podrías considerar Kubernetes para optimizaciones, pero para uso típico Docker es perfectamente eficiente.
¿Puedo correr WordPress y N8N en el mismo VPS?
Sí. Es el caso de uso ideal de Docker. Cada uno en su contenedor, sin que se afecten. Usa Nginx Proxy Manager o un reverse proxy para enrutar dominios distintos a cada contenedor.
¿Docker reemplaza a cPanel/Plesk?
Parcialmente. Docker es para correr apps; cPanel/Plesk gestionan correo, FTP, dominios, BD, SSL. Puedes usar ambos: Docker para apps modernas, ServerAvatar (gratis con VPS Moshipp) para el resto. O solo Docker si prefieres todo por terminal.
¿Qué pasa si elimino un contenedor? ¿Pierdo los datos?
Si los datos están en volúmenes Docker (no en el sistema de archivos del contenedor), NO los pierdes. Por eso siempre usa `volumes:` en compose. Solo si haces `docker volume rm` pierdes los datos.
¿Cuánta RAM consume cada contenedor?
Depende de la app. Un Nginx idle: 10 MB. WordPress + MySQL: 200-400 MB. N8N: 300-500 MB. PostgreSQL: 100-300 MB. Un VPS con 4 GB cómodamente corre 5-8 contenedores típicos.
¿Cómo actualizo una imagen Docker sin perder datos?
Con `docker compose pull` se baja la nueva versión. Con `docker compose down && docker compose up -d` la pones en marcha. Los volúmenes (datos) se preservan porque viven fuera del contenedor. Siempre haz backup antes.
¿Docker Swarm o Kubernetes?
Para 1 VPS: ninguno necesario, usa Docker Compose. Para varios servidores clustered: Docker Swarm es más simple, Kubernetes más potente pero complejo. La mayoría de PYMEs no necesita pasar de Compose.
Conclusión
Docker es una de las habilidades más rentables que puedes adquirir como dueño de VPS. Pasas de “instalo apps a mano y rezo que no rompa otras” a “describo lo que quiero en un YAML y se levanta”. Beneficios: reproducibilidad, aislamiento, escalabilidad y mantenimiento simplificado.
En esta guía instalaste Docker + Compose, viste 5 casos de uso reales (WordPress, N8N, PostgreSQL, Chatwoot, Nginx Proxy Manager) y mejores prácticas de seguridad. Con esto puedes empezar a desplegar apps modernas en tu VPS.
Si quieres un VPS optimizado para Docker, VPS Cloud de Moshipp viene con NVMe rápido, vCPU dedicada y ServerAvatar incluido sin costo para gestionar lo que prefieras visualmente. Y si quieres N8N pre-instalado, prueba el VPS N8N que llega con Docker, N8N y SSL configurados.
Sigue aprendiendo

Cómo conectar un dominio a un VPS (DNS, Nginx y SSL)
Tutorial completo para conectar un dominio a un VPS: configurar DNS, Nginx como servidor web e instalar SSL Let's Encrypt en menos de 30 minutos.
Leer más
Cómo proteger un VPS Linux: hardening básico paso a paso
Guía para endurecer la seguridad de un VPS Linux: SSH, firewall, fail2ban, actualizaciones automáticas y monitoreo. 12 medidas esenciales.
Leer más
Cómo instalar N8N en un VPS paso a paso (Ubuntu + Docker)
Tutorial completo para instalar N8N self-hosted en un VPS Ubuntu con Docker, Nginx y SSL gratuito. Guía probada de 30 minutos.
Leer más
