Hosting Equipo Avantys 8 min

Docker en VPS: Guía para Principiantes

Aprende a usar Docker en tu VPS desde cero. Instalación, conceptos básicos, comandos esenciales y ejemplos prácticos paso a paso.

// Compartir

Docker en VPS: Guía para Principiantes
Docker en VPS: Guía para Principiantes

Docker cambió cómo desplegamos aplicaciones. En lugar de configurar cada servidor manualmente, empaquetas tu app con todo lo que necesita y la ejecutas en cualquier lugar.

Para un VPS, Docker significa despliegues consistentes, aislamiento de aplicaciones y la posibilidad de correr múltiples servicios sin conflictos.

Esta guía te enseña Docker desde cero, orientado a uso en VPS.

Qué es Docker y por qué usarlo

El problema que resuelve

Sin Docker:

"Funciona en mi máquina" → No funciona en el servidor
- Diferentes versiones de PHP
- Librerías faltantes
- Configuraciones distintas

Con Docker:

"Funciona en mi máquina" → Funciona en todas partes
- El contenedor incluye todo
- Misma versión siempre
- Configuración idéntica

Beneficios en VPS

BeneficioExplicación
AislamientoCada app en su contenedor, sin conflictos
ConsistenciaMismo entorno en desarrollo y producción
PortabilidadMigrar a otro VPS es copiar contenedores
EscalabilidadLevantar más instancias fácilmente
LimpiezaBorrar app = borrar contenedor, sin residuos

Conceptos básicos

Conceptos básicos de Docker

Imagen (Image)

Una imagen es una plantilla de solo lectura. Contiene el sistema operativo, la aplicación y todas sus dependencias.

Imagen = Receta

Ejemplo: nginx:latest, wordpress:6.4, mysql:8

Contenedor (Container)

Un contenedor es una instancia ejecutándose de una imagen. Puedes tener múltiples contenedores de la misma imagen.

Contenedor = Plato preparado con la receta

Dockerfile

Archivo de texto con instrucciones para crear una imagen personalizada.

FROM php:8.3-fpm
RUN apt-get update && apt-get install -y libzip-dev
RUN docker-php-ext-install zip pdo_mysql
COPY . /var/www/html

Docker Compose

Herramienta para definir y ejecutar aplicaciones multi-contenedor. Un archivo YAML describe todos los servicios.

services:
  web:
    image: nginx
  db:
    image: mysql:8

Volumen (Volume)

Almacenamiento persistente. Los datos del contenedor se pierden al borrarlo; los volúmenes persisten.

Red (Network)

Permite que los contenedores se comuniquen entre sí de forma aislada.

Instalar Docker en tu VPS

Ubuntu/Debian

# Actualizar e instalar dependencias
sudo apt update
sudo apt install -y ca-certificates curl gnupg

# Añadir clave GPG oficial
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Añadir repositorio
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Instalar Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Verificar instalación

sudo docker run hello-world

Si ves el mensaje de bienvenida, Docker funciona.

Usar Docker sin sudo

sudo usermod -aG docker $USER
# Cierra sesión y vuelve a entrar

Comandos esenciales

Imágenes

# Descargar imagen
docker pull nginx

# Listar imágenes
docker images

# Eliminar imagen
docker rmi nginx

Contenedores

# Ejecutar contenedor
docker run nginx

# Ejecutar en segundo plano (-d = detached)
docker run -d nginx

# Ejecutar con nombre
docker run -d --name mi-nginx nginx

# Ejecutar con puerto mapeado
docker run -d -p 8080:80 nginx
# Accede en http://tu-ip:8080

# Listar contenedores activos
docker ps

# Listar todos (incluidos parados)
docker ps -a

# Parar contenedor
docker stop mi-nginx

# Iniciar contenedor parado
docker start mi-nginx

# Eliminar contenedor
docker rm mi-nginx

# Eliminar contenedor forzado (aunque esté corriendo)
docker rm -f mi-nginx

Logs y acceso

# Ver logs
docker logs mi-nginx

# Ver logs en tiempo real
docker logs -f mi-nginx

# Entrar al contenedor
docker exec -it mi-nginx bash
# Usa 'sh' si bash no está disponible

Limpieza

# Eliminar contenedores parados
docker container prune

# Eliminar imágenes sin usar
docker image prune

# Eliminar todo lo no usado (cuidado)
docker system prune -a

Workflow típico con Docker

Workflow de Docker

1. Definir con docker-compose.yml

version: '3.8'

services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
    restart: unless-stopped

2. Levantar servicios

docker compose up -d

3. Ver estado

docker compose ps

4. Ver logs

docker compose logs -f

5. Parar todo

docker compose down

Ejemplos prácticos

Ejemplo 1: Nginx simple

# docker-compose.yml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./sitio:/usr/share/nginx/html:ro
    restart: unless-stopped
mkdir sitio
echo "<h1>Hola desde Docker</h1>" > sitio/index.html
docker compose up -d

Visita http://tu-ip y verás tu página.

Ejemplo 2: WordPress completo

# docker-compose.yml
version: '3.8'

services:
  wordpress:
    image: wordpress:latest
    ports:
      - "80:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: secreto123
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress_data:/var/www/html
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: mysql:8
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: secreto123
      MYSQL_ROOT_PASSWORD: rootsecreto123
    volumes:
      - db_data:/var/lib/mysql
    restart: unless-stopped

volumes:
  wordpress_data:
  db_data:
docker compose up -d
# Espera 30 segundos y accede a http://tu-ip

WordPress funcionando con MySQL en minutos.

Ejemplo 3: Aplicación Node.js

Dockerfile:

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

docker-compose.yml:

version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      NODE_ENV: production
    restart: unless-stopped
docker compose up -d --build

Volúmenes: datos persistentes

Por qué importan

Sin volúmenes, los datos se pierden al eliminar el contenedor:

docker run -d --name mi-mysql mysql:8
docker rm -f mi-mysql
# ¡Datos perdidos!

Con volúmenes, persisten:

docker run -d --name mi-mysql -v mysql_data:/var/lib/mysql mysql:8
docker rm -f mi-mysql
docker run -d --name mi-mysql-nuevo -v mysql_data:/var/lib/mysql mysql:8
# ¡Datos recuperados!

Tipos de volúmenes

Volumen nombrado (recomendado):

volumes:
  - mysql_data:/var/lib/mysql

Bind mount (carpeta del host):

volumes:
  - ./datos:/var/lib/mysql

Volumen anónimo (no recomendado):

volumes:
  - /var/lib/mysql

Gestionar volúmenes

# Listar volúmenes
docker volume ls

# Inspeccionar volumen
docker volume inspect mysql_data

# Eliminar volumen
docker volume rm mysql_data

# Eliminar volúmenes sin usar
docker volume prune

Redes en Docker

Red por defecto

Docker Compose crea una red automática donde los servicios se ven por nombre:

services:
  web:
    image: nginx
  db:
    image: mysql

web puede conectar a db usando db como hostname.

Red personalizada

services:
  web:
    networks:
      - frontend
      - backend
  db:
    networks:
      - backend

networks:
  frontend:
  backend:

db solo es accesible desde backend, no desde frontend.

Docker con proxy inverso

Para múltiples aplicaciones en el mismo VPS:

Traefik (recomendado)

# docker-compose.yml
version: '3.8'

services:
  traefik:
    image: traefik:v2.10
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
      - "[email protected]"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - letsencrypt:/letsencrypt
    restart: unless-stopped

volumes:
  letsencrypt:

Luego cada app se registra automáticamente:

services:
  mi-app:
    image: mi-app
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.miapp.rule=Host(`miapp.tudominio.com`)"
      - "traefik.http.routers.miapp.tls.certresolver=letsencrypt"

Seguridad básica

No correr como root

FROM node:20-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

No exponer puertos innecesarios

Solo expón lo necesario:

services:
  db:
    image: mysql
    # NO hagas esto:
    # ports:
    #   - "3306:3306"
    # La BD solo debe ser accesible internamente

Usar imágenes oficiales

Prefiere nginx:alpine sobre random-user/nginx.

Variables de entorno para secretos

services:
  db:
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt

Recursos y límites

Evita que un contenedor consuma todo el VPS:

services:
  app:
    image: mi-app
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M

Backups de contenedores

Backup de volúmenes

# Crear backup
docker run --rm -v mysql_data:/data -v $(pwd):/backup alpine tar cvf /backup/mysql_backup.tar /data

# Restaurar
docker run --rm -v mysql_data:/data -v $(pwd):/backup alpine tar xvf /backup/mysql_backup.tar -C /

Backup de base de datos

docker exec mi-mysql mysqldump -u root -p'password' --all-databases > backup.sql

Errores comunes

Error 1: Puerto ya en uso

Error: bind: address already in use

Solución: Otro servicio usa ese puerto. Cambia el puerto o para el servicio conflictivo.

Error 2: Permisos de volumen

Permission denied

Solución: Ajusta permisos o usa user: en el compose.

Error 3: Contenedor se reinicia constantemente

docker logs mi-contenedor

Revisa los logs para ver el error.

Error 4: Sin espacio en disco

docker system prune -a

Limpia imágenes y contenedores no usados.

Docker vs instalación tradicional

AspectoDockerTradicional
InstalaciónUn comandoMúltiples pasos
ConsistenciaSiempre igualVaría por servidor
AislamientoTotalCompartido
RecursosLigero overheadNativo
ComplejidadCurva inicialFamiliar
MigraciónFácilManual

Cuándo usar Docker en VPS

Sí usar Docker si:

  • Despliegas múltiples aplicaciones
  • Necesitas entornos reproducibles
  • Trabajas con microservicios
  • Quieres facilitar migraciones
  • Tu equipo ya conoce Docker

Quizás no si:

  • Solo tienes una app simple (WordPress básico)
  • VPS con muy poca RAM (<2GB)
  • No tienes tiempo para aprender
  • Tu hosting ya gestiona todo

Preguntas frecuentes

¿Docker consume mucha RAM?

El engine consume ~100MB. Cada contenedor suma según la app. Mínimo recomendado: 2GB de RAM en el VPS.

¿Puedo usar Docker con panel como cPanel?

Técnicamente sí, pero no es ideal. Docker funciona mejor gestionado directamente o con paneles específicos como Portainer.

¿Los contenedores son seguros?

Sí, con buenas prácticas. Aíslan aplicaciones pero comparten kernel. No es virtualización completa.

¿Puedo hacer Docker de mi WordPress existente?

Sí, pero requiere migrar datos. Para WordPress nuevo, Docker es excelente. Para existente, evalúa si vale la pena.

Nuestra recomendación

Para empezar: Docker Compose con ejemplos simples. Un WordPress dockerizado te enseña los conceptos.

Para producción: Añade Traefik para múltiples dominios y SSL automático.

Si no quieres complicarte: Los VPS de Avantys con administración gestionada pueden incluir configuración Docker profesional.


Conclusión

Docker simplifica despliegues y hace tu VPS más organizado. La curva de aprendizaje inicial vale la pena por la consistencia y facilidad de gestión que ganas.

Empieza con ejemplos simples, entiende los conceptos, y gradualmente dockeriza más servicios. En poco tiempo, no querrás volver a instalaciones tradicionales.

¿Quieres un VPS preparado para Docker? Explora los VPS de Avantys con soporte completo.


Guías relacionadas


¿Quieres la guía completa con todos los casos de uso?

→ Volver a la guía maestra: Mejor VPS en España 2026

¿Quieres que lo hagamos por ti?

En Avantys gestionamos tu web, hosting y crecimiento digital de punta a punta. Tú a lo importante.

Hablar con Avantys
// Boletín

Suscríbete al boletín

Guías nuevas, sin spam. Cancela cuando quieras.