Portainer Community Edition (CE) es una interfaz web para gestionar Docker: contenedores, imágenes, volúmenes, redes y stacks de Docker Compose, en uno o varios servidores. En este tutorial instalarás Portainer CE en Ubuntu 24.04, lo publicarás detrás de Nginx con un certificado de Let's Encrypt, conectarás un segundo servidor mediante el agente de Portainer y desplegarás un stack de ejemplo.

Requisitos previos

Para seguir esta guía necesitas:

  • Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 1 GB de RAM.
  • Un usuario no root con privilegios sudo.
  • Docker Engine y el plugin Docker Compose instalados desde el repositorio oficial de Docker.
  • Un subdominio (en esta guía, portainer.your_domain) con un registro DNS A que apunte a la IP pública del servidor.
  • Los puertos 80 y 443 accesibles desde Internet.
  • Opcional: un segundo servidor con Docker para el paso 6, idealmente conectado al primero por una red privada.

Comprueba que Docker funciona:

sudo docker version --format '{{.Server.Version}}'

Paso 1: Crear el volumen de datos

Portainer guarda su base de datos, usuarios y ajustes en /data dentro del contenedor. Crea un volumen con nombre para que esos datos sobrevivan a las actualizaciones:

sudo docker volume create portainer_data

Paso 2: Arrancar el contenedor de Portainer

Ejecuta Portainer CE con la etiqueta lts, que apunta a la última versión de soporte extendido:

sudo docker run -d \
  --name portainer \
  --restart=always \
  -p 127.0.0.1:9443:9443 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer-ce:lts

La interfaz escucha en el puerto 9443 con un certificado autofirmado. Se publica solo en 127.0.0.1 porque Docker crea sus propias reglas de iptables y un puerto publicado en todas las interfaces quedaría abierto aunque UFW lo bloquee; el acceso externo pasará por Nginx. El puerto 8000 que aparece en la documentación oficial solo hace falta para agentes Edge, que esta guía no usa.

Comprueba que el contenedor está en marcha y que responde:

sudo docker ps --filter name=portainer
curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1:9443
200

Paso 3: Publicar Portainer con Nginx y HTTPS

Instala Nginx y Certbot:

sudo apt update
sudo apt install nginx certbot python3-certbot-nginx

Crea el bloque de servidor:

sudo nano /etc/nginx/sites-available/portainer

Añade esta configuración. Nginx reenvía el tráfico al puerto HTTPS de Portainer sin verificar su certificado autofirmado (la conexión es local), y las cabeceras Upgrade y Connection permiten abrir la consola de los contenedores, que usa WebSocket:

server {
    listen 80;
    listen [::]:80;
    server_name portainer.your_domain;

    client_max_body_size 100M;

    location / {
        proxy_pass https://127.0.0.1:9443;
        proxy_ssl_verify off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Activa el sitio y recarga Nginx:

sudo ln -s /etc/nginx/sites-available/portainer /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Si usas UFW, permite SSH y el tráfico web:

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable

Obtén el certificado. Certbot añadirá la configuración TLS y la redirección de HTTP a HTTPS:

sudo certbot --nginx -d portainer.your_domain

Comprueba que la renovación automática funcionará:

sudo certbot renew --dry-run

Paso 4: Crear el usuario administrador

Abre https://portainer.your_domain en el navegador. Portainer muestra el asistente inicial:

  1. Escribe un nombre de usuario para el administrador (evita admin) y una contraseña de al menos 12 caracteres.
  2. Pulsa Create user.
  3. En la pantalla siguiente, pulsa Get Started. Portainer detecta el socket de Docker montado y crea el entorno local.

Entra en Home y abre el entorno local. En el panel verás el número de contenedores, imágenes, volúmenes y redes del servidor, incluido el propio contenedor portainer.

Paso 5: Desplegar un stack de Docker Compose

Los stacks son la forma más cómoda de desplegar aplicaciones desde Portainer: pegas un archivo de Compose y Portainer lo crea y lo guarda para poder editarlo después.

  1. En el entorno local, abre Stacks y pulsa Add stack.
  2. Escribe whoami como nombre.
  3. En Web editor, pega el siguiente contenido.
  4. Pulsa Deploy the stack.
services:
  whoami:
    image: traefik/whoami:latest
    restart: unless-stopped
    ports:
      - "127.0.0.1:8081:80"

Verifica desde el servidor que el contenedor responde:

curl -s http://127.0.0.1:8081
Hostname: 3f2a9c1b7d4e
IP: 127.0.0.1
IP: 172.18.0.2
RemoteAddr: 172.18.0.1:53422
GET / HTTP/1.1
Host: 127.0.0.1:8081

Desde la página del stack puedes editar el archivo, volver a desplegarlo con Update the stack o eliminarlo. En Containers tienes, para cada contenedor, los registros (Logs), estadísticas en vivo (Stats) y una consola (Console).

Paso 6: Gestionar un servidor remoto con el agente

Para administrar otro servidor Docker desde la misma interfaz, instala en él el agente de Portainer. El agente escucha en el puerto 9001 y da control total sobre ese Docker, así que publícalo solo en la IP privada del servidor remoto (sustituye your_private_ip):

sudo docker run -d \
  --name portainer_agent \
  --restart=always \
  -p your_private_ip:9001:9001 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /var/lib/docker/volumes:/var/lib/docker/volumes \
  -v /:/host \
  portainer/agent:lts

La versión del agente debe coincidir con la del servidor de Portainer; usar lts en ambos lados lo garantiza mientras los actualices a la vez.

Después, en Portainer:

  1. Abre Environment-related y luego Environments, y pulsa Add environment.
  2. Elige Docker Standalone y pulsa Start Wizard.
  3. Selecciona Agent, escribe un nombre y en Environment address indica your_private_ip:9001.
  4. Pulsa Connect.

El nuevo entorno aparece en Home con el estado Up y la versión de Docker del servidor remoto.

Paso 7: Copias de seguridad y actualizaciones

Portainer CE permite descargar una copia de su configuración desde Settings, sección Back up Portainer: pulsa Download backup file y, si quieres, protégela con contraseña. Esa copia se restaura desde el asistente inicial de una instalación nueva.

También puedes copiar el volumen completo desde la línea de comandos. Detén Portainer para que la base de datos no cambie durante la copia:

sudo mkdir -p /var/backups/portainer
sudo docker stop portainer
sudo docker run --rm \
  -v portainer_data:/data:ro \
  -v /var/backups/portainer:/backup \
  alpine tar -czf "/backup/portainer-$(date +%Y%m%d).tar.gz" -C /data .
sudo docker start portainer

Para actualizar Portainer, elimina el contenedor (el volumen portainer_data se conserva), descarga la imagen nueva y vuelve a crearlo con el mismo comando del paso 2:

sudo docker stop portainer
sudo docker rm portainer
sudo docker pull portainer/portainer-ce:lts
sudo docker run -d \
  --name portainer \
  --restart=always \
  -p 127.0.0.1:9443:9443 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v portainer_data:/data \
  portainer/portainer-ce:lts

Actualiza también los agentes remotos con el mismo procedimiento usando la imagen portainer/agent:lts.

Solución de problemas

  • 502 Bad Gateway: Nginx no llega a 127.0.0.1:9443. Comprueba que el contenedor está en marcha con sudo docker ps y revisa sudo docker logs portainer.
  • Aviso de que la instancia se ha bloqueado por seguridad: no se creó el administrador a tiempo. Ejecuta sudo docker restart portainer y crea el usuario de inmediato.
  • La consola del contenedor no conecta: faltan las cabeceras Upgrade y Connection en el bloque de Nginx.
  • El entorno remoto aparece como Down: comprueba desde el servidor de Portainer que llegas al agente con nc -zv your_private_ip 9001 y que ambas versiones coinciden.

Conclusión

Ya tienes Portainer CE funcionando detrás de Nginx con HTTPS, un stack desplegado desde la interfaz y, si lo has configurado, un segundo servidor gestionado con el agente. Como siguientes pasos, crea usuarios adicionales con permisos limitados en Users, conecta tus stacks a un repositorio Git desde la opción Repository al crearlos y programa la copia del volumen con cron.