Mascota Jacar — leyendo contigo Un portátil cuyos ojos siguen el cursor mientras lees.
Cómo Instalar

Cómo instalar Portainer con Docker Compose v2

Cómo instalar Portainer con Docker Compose v2

Más sobre este artículo

Resumen rápido
  • Portainer CE, la UI web de gestión de contenedores Docker, se instala con Docker Compose v2 mediante un único `compose.yaml` de 15 líneas sin clave `version:`.
  • Pinea la imagen a `portainer/portainer-ce:2.40.0` en lugar de `:latest` para controlar exactamente cuándo se actualiza el servidor.
  • El volumen nombrado `portainer_data` conserva usuarios, endpoints y configuración entre actualizaciones sin pérdida de datos.
  • El socket Docker se monta en solo-lectura (`:ro`) porque Portainer gestiona los contenedores vía API REST y no necesita acceso de escritura al socket del host.
Conceptos clave
  • Requisitos previos: Docker Engine 24+ con el plugin `docker compose` integrado, acceso sudo y el puerto 9443 libre.
  • Preparar compose.yaml: Fichero de 15 líneas con imagen pineada, volumen nombrado y socket Docker en solo-lectura.
  • Lanzar el contenedor: Un único `docker compose up -d` arranca Portainer con HTTPS en el puerto 9443.
Enlaces útiles
Sigue leyendo

Actualizado: 2026-05-16

Portainer[1] es la UI web de referencia para gestionar contenedores Docker, stacks de Compose y clusters Swarm/Kubernetes. La edición CE 2.40 STS incluye soporte nativo de Docker Compose v2, HTTPS por defecto en el puerto 9443, y un panel unificado para recursos Docker Engine, Swarm, Kubernetes y ACI.

Esta guía instala Portainer CE con Docker Compose v2 en un servidor Debian/Ubuntu moderno (Ubuntu 24.04 LTS / Debian 13 Trixie), usando un fichero compose.yaml y el plugin oficial docker compose (sin guion, incluido con Docker Engine 20.10+).

Puntos clave

  • Usa compose.yaml (sin clave version:) en lugar del antiguo docker-compose.yml con versión explícita.
  • Pinea la imagen (portainer/portainer-ce:2.40.0) en lugar de :latest para evitar upgrades silenciosos.
  • El volumen nombrado (portainer_data) simplifica backups y actualizaciones.
  • El socket Docker se monta en solo-lectura (:ro): Portainer no necesita escritura directa al socket.
  • El formulario de primer acceso expira a los 5 minutos: tenlo todo preparado antes de abrir el navegador.

Requisitos previos

Antes de empezar, necesitas:

  • Servidor con Docker Engine 24+ instalado (incluye el plugin docker compose por defecto). Ver la guía oficial de Docker para Debian[2] o Ubuntu[3].
  • Acceso sudo o usuario en el grupo docker.
  • Puerto 9443 libre para la UI HTTPS y, opcionalmente, el 8000 para el Edge Agent Tunnel.

Preparar el fichero compose.yaml

Crea el directorio de trabajo y el fichero de configuración:

javascript
mkdir -p ~/docker/portainer
cd ~/docker/portainer
nano compose.yaml

Contenido recomendado:

yaml
services:
  portainer:
    image: portainer/portainer-ce:2.40.0
    container_name: portainer
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    ports:
      - "9443:9443"   # UI HTTPS
      - "8000:8000"   # Edge Agent tunnel (opcional)
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - portainer_data:/data

volumes:
  portainer_data:

Diferencias respecto a guías antiguas que vale la pena conocer:

  • Sin clave version:. La Compose Specification la ignora desde 2023; hoy es redundante y genera advertencias en algunas versiones.
  • Nombre compose.yaml preferido sobre docker-compose.yml (ambos funcionan, pero el nuevo es el estándar oficial).
  • Imagen pineada a 2.40.0, no :latest. El pinning evita sorpresas por upgrades mayores silenciosos cuando el host lanza un pull.
  • Volumen nombrado (portainer_data) en lugar de bind-mount. Lo gestiona Docker directamente y facilita backups con herramientas como restic[4] o docker cp.
  • Socket Docker en solo-lectura (:ro). Portainer controla todo vía API, no necesita escritura directa al socket del host.
Panel de administración de Portainer CE mostrando la lista de contenedores Docker en ejecución

Panel de administración de Portainer CE mostrando la lista de contenedores Docker en ejecución

Lanzar el contenedor

Con el fichero compose.yaml en su lugar, levanta Portainer en segundo plano:

nginx
docker compose up -d
docker compose ps

Verás un contenedor portainer corriendo y escuchando en 0.0.0.0:9443. Si el comando docker compose no existe, asegúrate de estar usando Docker Engine 20.10+ con el plugin integrado, no la versión legada docker-compose (con guion).

Primer acceso

Abre en el navegador:

https://<IP-o-dominio>:9443

La primera vez te pedirá crear el usuario admin con una contraseña mínima de 12 caracteres. El formulario expira a los 5 minutos desde que arranca el contenedor, si tardas, reinicia con docker compose restart y vuelve a entrar.

Como el certificado HTTPS es autofirmado en primera instalación, tu navegador avisará de «conexión no privada». Es normal; pulsa «Avanzado → Continuar» para acceder. Para producción, coloca Portainer detrás de un reverse proxy como Traefik[5] con Let’s Encrypt automático (ver más abajo).

Actualizar Portainer a una nueva versión

Actualizar Portainer es seguro porque el volumen portainer_data persiste usuarios, endpoints y configuración entre versiones:

css
# 1) Editar compose.yaml y cambiar la tag (p.ej. 2.40.0 -> 2.41.0)
# 2) Pull + recreate:
docker compose pull
docker compose up -d
# 3) Limpiar imagen anterior (opcional):
docker image prune -f

El volumen garantiza que la actualización no pierde datos. Si algo va mal, simplemente edita la tag al valor anterior y vuelve a hacer docker compose up -d.

Exponer Portainer con Traefik (opcional)

Si ya tienes Traefik como ingress con red traefik_public definida, añade labels al servicio y quita el mapping de puertos. Cuando Traefik termina TLS por ti, el puerto interno es 9000 (HTTP), no 9443:

yaml
services:
  portainer:
    image: portainer/portainer-ce:2.40.0
    restart: unless-stopped
    networks: [traefik_public]
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - portainer_data:/data
    labels:
      - traefik.enable=true
      - traefik.http.routers.portainer.rule=Host(`portainer.example.com`)
      - traefik.http.routers.portainer.entrypoints=websecure
      - traefik.http.routers.portainer.tls.certresolver=letsencrypt
      - traefik.http.services.portainer.loadbalancer.server.port=9000
      - traefik.http.services.portainer.loadbalancer.server.scheme=http

networks:
  traefik_public:
    external: true

volumes:
  portainer_data:

Con esta configuración, Traefik gestiona el certificado TLS con Let’s Encrypt y Portainer queda accesible en https://portainer.example.com sin puertos no estándar. El mismo patrón aplica a cualquier servicio adicional que despliegues, ver cómo instalar servidores MCP locales como ejemplo de servicio complementario.

Conclusión

La instalación moderna de Portainer con Compose v2 es más limpia y robusta que las guías de hace tres años: un compose.yaml de 15 líneas, versión pineada, HTTPS por defecto, y persistencia en volumen nombrado. Para entornos con varios nodos, Swarm o Kubernetes, Portainer añade la misma UI sobre el endpoint del cluster sin cambiar el patrón de despliegue de esta guía.

Lo esencial que no cambia entre versiones:

  • Pinea la imagen para controlar cuándo actualizas.
  • Usa volumen nombrado, no bind-mount, para la carpeta /data.
  • Monta el socket en solo-lectura.
  • Pon un reverse proxy con TLS en producción.
¿Te ha resultado útil?
[Total: 7 · Media: 4.7]
  1. Portainer
  2. guía oficial de Docker para Debian
  3. Ubuntu
  4. restic
  5. Traefik

Escrito por

CEO - Jacar Systems

Apasionado de la tecnología, la infraestructura cloud y la inteligencia artificial. Escribe sobre DevOps, IA, plataformas y software desde Madrid.