Cómo instalar Portainer con Docker Compose v2
Índice de contenidos
- Puntos clave
- Requisitos previos
- Preparar el fichero compose.yaml
- Lanzar el contenedor
- Primer acceso
- Actualizar Portainer a una nueva versión
- Exponer Portainer con Traefik (opcional)
- Preguntas frecuentes
- ¿Portainer sustituye a la línea de comandos de Docker?
- ¿Es seguro exponer Portainer directamente a internet en el puerto 9443?
- ¿Puedo gestionar varios servidores Docker desde un único Portainer?
- Conclusión
- Fuentes
Probado con Portainer CE 2.40.0 · Docker Compose v2 · verificado
Actualizado: 2026-07-17
Portainer es la UI web de referencia para gestionar contenedores Docker, stacks de Compose y clusters Swarm/Kubernetes. Guía paso a paso con compose.yaml moderno, HTTPS en el puerto 9443, volumen nombrado y configuración opcional con Traefik.
Portainer[1] es la interfaz web de referencia para administrar contenedores Docker, stacks de Docker Compose (la herramienta que define y levanta varios contenedores a partir de un fichero YAML) y clústeres Swarm o Kubernetes desde un panel único, y se instala con un solo fichero compose.yaml y dos comandos. La edición CE 2.40 STS añade soporte nativo de Docker Compose v2, HTTPS activado por defecto en el puerto 9443 y un panel unificado para recursos de Docker Engine, Swarm, Kubernetes y ACI. La misma guía está disponible en inglés.
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 guión, incluido con Docker Engine 20.10+; sustituye al binario independiente docker-compose de la generación anterior).
Puntos clave
- Usa
compose.yaml(sin claveversion:) en lugar del antiguodocker-compose.ymlcon versión explícita. - Pinea la imagen (
portainer/portainer-ce:2.40.0) en lugar de:latestpara evitar actualizaciones silenciosas. - El volumen nombrado (
portainer_data) simplifica copias de seguridad 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 composepor defecto). Ver la guía oficial de Docker para Debian[2] o Ubuntu[3]. - Acceso
sudoo usuario en el grupodocker. - Puerto
9443libre para la UI HTTPS y, opcionalmente, el8000para el Edge Agent Tunnel (el canal que usa Portainer para gestionar agentes remotos sin abrirles puertos entrantes).
Preparar el fichero compose.yaml
Crea el directorio de trabajo y el fichero de configuración:
mkdir -p ~/docker/portainer
cd ~/docker/portainer
nano compose.yaml
Contenido recomendado:
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.yamlpreferido sobredocker-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 actualizaciones mayores silenciosas cuando el host lanza un pull. - Volumen nombrado (
portainer_data) en lugar de bind-mount. Lo gestiona Docker directamente y facilita copias de seguridad con herramientas como restic[4] odocker 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
Lanzar el contenedor
Con el fichero compose.yaml en su lugar, levanta Portainer en segundo plano:
docker compose up -d
docker compose ps
Verás un contenedor portainer en ejecución 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 heredada docker-compose (con guión, ya sin mantenimiento activo).
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 más, reinicia con docker compose restart y vuelve a entrar.
Como el certificado HTTPS es autofirmado en la primera instalación, tu navegador avisará de «conexión no privada». Es normal: pulsa «Avanzado» y luego «Continuar» para acceder. Para producción, coloca Portainer detrás de un reverse proxy como Traefik (el proxy inverso que reparte el tráfico HTTPS entre contenedores y renueva los certificados de forma automática) con Let’s Encrypt (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. El proceso tiene tres pasos: edita compose.yaml y cambia la etiqueta de imagen (por ejemplo de 2.40.0 a 2.41.0), descarga la nueva imagen y recrea el contenedor, y por último limpia la imagen anterior si quieres liberar espacio:
docker compose pull
docker compose up -d
docker image prune -f
El volumen garantiza que la actualización no pierde datos. Si algo va mal, edita la etiqueta al valor anterior y vuelve a ejecutar docker compose up -d. Si prefieres automatizar por completo este paso, revisa cómo instalar Watchtower, la herramienta que vigila tus imágenes y recrea los contenedores cuando hay una versión nueva.
Exponer Portainer con Traefik (opcional)
Si ya tienes Traefik como ingress con la red traefik_public definida, añade labels al servicio y quita el mapeo de puertos. Cuando Traefik termina TLS por ti, el puerto interno es 9000 (HTTP), no 9443:
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.
Preguntas frecuentes
¿Portainer sustituye a la línea de comandos de Docker?
No del todo. Portainer cubre la mayor parte del día a día (arrancar, parar, inspeccionar logs, desplegar stacks, gestionar volúmenes y redes) desde el navegador, pero para depuración fina o scripts automatizados seguirás usando docker y docker compose por terminal. Ambos leen el mismo socket, así que los cambios hechos por uno se ven al instante en el otro.
¿Es seguro exponer Portainer directamente a internet en el puerto 9443?
Funciona, pero no es lo recomendable a largo plazo: el formulario de primer acceso expira en 5 minutos precisamente para reducir ese riesgo, y después conviene añadir autenticación adicional. Lo más seguro es colocarlo detrás de un reverse proxy con TLS válido y, si es posible, restringir el acceso por IP o VPN en lugar de dejarlo accesible a cualquiera.
¿Puedo gestionar varios servidores Docker desde un único Portainer?
Sí. Además del entorno local, Portainer conecta con endpoints remotos vía el Edge Agent (un pequeño contenedor que se instala en cada servidor y abre un túnel saliente hacia tu Portainer central) o vía API TLS directa, lo que permite administrar varios hosts, un clúster Swarm o Kubernetes desde el mismo panel.
Conclusión
La instalación moderna de Portainer con Compose v2 es más sencilla 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 clúster 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.
Fuentes: [1] Documentación oficial de Portainer CE (instalación con Docker)[5], [2] Documentación oficial de Docker Compose[6], [3] Documentación oficial de Traefik[7], [4] Documentación de restic[4].