Saltar al contenido principal
VPS

Cómo instalar Docker en un VPS Ubuntu (con ejemplos prácticos)

Tutorial completo para instalar Docker y Docker Compose en un VPS Ubuntu. Incluye casos de uso reales: WordPress, N8N, PostgreSQL y más.

Equipo Moshipp11 de junio de 202612 min de lectura
Contenedores apilados en un puerto industrial representando el concepto de Docker
Foto: Unsplash

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.yml y 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

Migración sin complicaciones

¿Migrar desde otro proveedor de hosting?

¿Estás cansado de la falta de rapidez y seguridad en tu sitio web? ¡Migra a Moshipp y obtén un servicio de hosting de calidad superior!

Más de 10,000 sitios web migrados con éxito