Requisitos
Instala primero Docker desde el repositorio oficial. Comprueba docker version y espacio disponible. No publiques Portainer en un VPS sin firewall y contraseña robusta.
Desplegar Portainer CE
La documentación ofrece ramas LTS y STS. Elige conscientemente la indicada para tu operación. Crea el volumen y ejecuta:
docker volume create portainer_data
docker run -d --name portainer --restart=always \
-p 9443:9443 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:lts El puerto 8000 es opcional para Edge Agents; no lo publiques si no lo necesitas. Verifica:
docker ps
docker logs --tail=100 portainer Abre https://IP_DEL_VPS:9443. El certificado inicial es autofirmado. Crea enseguida el administrador y conecta el entorno local.
Limitar la exposición
La mejor opción es permitir 9443 únicamente desde tu IP, VPN o red administrativa. Otra alternativa es enlazarlo a 127.0.0.1 y publicarlo detrás de un proxy con autenticación y TLS confiable.
Docker puede insertar reglas que evitan UFW. Comprueba desde otra red qué puertos están realmente abiertos y utiliza el firewall del proveedor cuando esté disponible.
Backups y actualizaciones
El volumen portainer_data conserva configuración, pero no contiene automáticamente los datos de todos tus contenedores. Respáldalo junto con las aplicaciones. Antes de actualizar, revisa notas de versión y conserva un rollback.
Portainer ayuda a visualizar Docker Compose, pero los archivos versionados siguen siendo una fuente de verdad más reproducible que cambios manuales sin documentación.
Qué administra Portainer realmente
Portainer es una interfaz sobre Docker, no un reemplazo del motor ni de Docker Compose. Cuando creas un contenedor, una red o un volumen desde el panel, Portainer llama a la API del daemon. Si el panel deja de funcionar, los contenedores continúan; puedes examinarlos con el cliente Docker y recuperar la interfaz sin reconstruir las aplicaciones.
Esa arquitectura explica dos decisiones importantes. Primero, el acceso al panel es acceso administrativo al host. Segundo, los archivos Compose guardados en Git siguen siendo una fuente más portátil que una colección de clics. Portainer aporta visibilidad y control cotidiano, mientras que la infraestructura declarada permite repetir el despliegue.
Comprueba el motor antes de instalar:
docker version
docker info
docker compose version
systemctl is-active docker Si el cliente no puede hablar con el daemon, resuelve ese problema primero. Volver a ejecutar docker run con sudo puede ocultar que tu usuario carece de permisos, pero no arregla un servicio Docker detenido o dos instalaciones en conflicto.
Desplegar Portainer con una versión controlada
La etiqueta elegida determina el canal de actualización; no cambies entre ramas sin revisar compatibilidad y notas de versión. El comando inicial del artículo usa la rama LTS. Registra el identificador de imagen después de descargarla para saber qué binario quedó instalado.
docker pull portainer/portainer-ce:lts
docker image inspect portainer/portainer-ce:lts \
--format '{{index .RepoDigests 0}}'
docker volume inspect portainer_data El volumen debe existir antes de arrancar porque almacena usuarios, endpoints y configuración. El socket se monta como archivo del host:
docker inspect portainer --format '{{json .Mounts}}' Verás un montaje para /data y otro para /var/run/docker.sock. El primero es persistencia; el segundo es autoridad. No confundas ambos ni copies el socket a una ubicación pública.
Cuando abras el panel por primera vez, crea la cuenta administrativa sin demora. Usa una contraseña única guardada en un gestor y no dejes el formulario inicial expuesto durante horas. Si la instalación se realiza remotamente, limita temporalmente el puerto a tu IP desde el firewall del proveedor antes de iniciar el contenedor.
Restringir el panel a loopback o una VPN
La opción más segura para un panel que usas ocasionalmente es no publicarlo directamente en internet. Puedes enlazar 9443 a loopback y entrar mediante túnel SSH:
docker stop portainer
docker rm portainer
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 Desde tu computador crea el túnel:
ssh -L 9443:127.0.0.1:9443 usuario@IP_DEL_VPS Mientras esa sesión permanezca abierta, visita https://127.0.0.1:9443. El certificado seguirá mostrando una advertencia por nombre, pero el puerto no aceptará tráfico directo desde internet.
Si varias personas necesitan acceso, una VPN WireGuard ofrece una dirección administrativa estable. Otra posibilidad es un proxy reverso con certificado válido y una política adicional de acceso. En cualquiera de los casos, prueba desde una red externa que la IP pública no responde en 9443.
sudo ss -ltnp | grep 9443
docker port portainer La salida esperada para loopback contiene 127.0.0.1:9443, no 0.0.0.0:9443 ni [::]:9443.
Usar Nginx como entrada HTTPS
Un proxy permite usar un dominio y certificado confiable sin entregar el puerto de Portainer a toda la red. Mantén el contenedor enlazado a loopback y configura un sitio administrativo en Nginx:
server {
listen 443 ssl http2;
server_name portainer.ejemplo.com;
ssl_certificate /etc/letsencrypt/live/portainer.ejemplo.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/portainer.ejemplo.com/privkey.pem;
location / {
proxy_pass https://127.0.0.1:9443;
proxy_ssl_verify off;
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;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
} proxy_ssl_verify off se aplica únicamente al salto local hacia el certificado autofirmado, no al certificado público presentado al navegador. Mantén este proxy accesible solo por VPN o IP si el equipo no necesita entrada global. Valida siempre antes de recargar:
sudo nginx -t
sudo systemctl reload nginx
curl -I https://portainer.ejemplo.com No desactives TLS en el panel para “simplificar” la configuración. Aunque el salto sea local, conservar HTTPS evita cambios innecesarios y mantiene un comportamiento coherente si más adelante mueves el servicio.
Endpoints locales y remotos
El entorno local usa el socket del mismo host; un entorno remoto necesita un método de conexión diseñado para ello. No publiques el socket Docker por TCP sin autenticación y cifrado: quien acceda puede tomar el control del servidor.
Para administrar varios VPS, evalúa el agente de Portainer y las funciones compatibles con tu edición. El agente también es una superficie administrativa; limita su red a las direcciones de gestión y no abras puertos “por si acaso”. Documenta qué panel controla cada endpoint para evitar que dos administradores apliquen cambios contradictorios.
Si un endpoint aparece desconectado, separa las causas:
- El daemon Docker del endpoint está detenido.
- El agente o contenedor de Portainer no está en ejecución.
- Una regla de red bloquea la comunicación.
- La dirección configurada cambió.
- La versión de los componentes no es compatible.
Empieza por el host afectado con docker ps, docker logs y una prueba de red. Reiniciar el panel central no recupera un daemon remoto caído.
Stacks reproducibles en lugar de cambios invisibles
Un stack es útil cuando su definición tiene historial y un responsable claro. Puedes pegar un archivo Compose en la interfaz, pero para producción conviene vincularlo a un repositorio o conservar la misma definición fuera del panel.
Antes de desplegar revisa:
docker compose -f compose.yaml config --quiet
git diff -- compose.yaml Evita incluir contraseñas directamente en el YAML. Portainer puede administrar variables según el método del stack, pero el equipo debe saber dónde se guardan y cómo restaurarlas. Un repositorio sin secretos más un inventario seguro de variables permite reconstruir el servicio.
Los cambios hechos directamente a un contenedor creado por un stack se pierden cuando el stack lo recrea. Si necesitas cambiar un puerto, volumen o variable, modifica la definición y vuelve a desplegar. Así la configuración observada coincide con la declarada.
Inspeccionar contenedores sin confundir síntomas
El panel facilita ver estado, logs y estadísticas, pero debes interpretar cada señal. “Running” significa que el proceso principal sigue vivo; no prueba que la aplicación responda a una solicitud ni que su base esté disponible. Añade healthchecks y realiza una prueba desde el punto de vista del usuario.
Desde la terminal puedes corroborar lo que ves:
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
docker logs --tail=200 --timestamps NOMBRE_CONTENEDOR
docker stats --no-stream
docker inspect NOMBRE_CONTENEDOR --format '{{json .State.Health}}' La interfaz de estadísticas es una foto actual. Para diagnosticar picos nocturnos necesitas métricas históricas fuera de Portainer. Del mismo modo, descargar logs manualmente no sustituye rotación ni centralización cuando existe una obligación de auditoría.
Administrar volúmenes sin borrar datos por accidente
Un volumen marcado como “unused” puede contener la única copia de datos de un contenedor detenido. Antes de eliminarlo, inspecciona su nombre, etiquetas y consumidores:
docker volume inspect NOMBRE_VOLUMEN
docker ps -a --filter volume=NOMBRE_VOLUMEN
docker system df -v No uses una limpieza masiva desde la interfaz durante un incidente de disco sin identificar qué puede recuperarse. Libera primero archivos temporales conocidos o imágenes verificadamente reemplazables. Los volúmenes requieren una decisión de datos, no una decisión de espacio.
Para una base, produce un volcado consistente desde su propio motor. Para archivos, detén o coordina escrituras si el formato lo requiere. Copia el resultado fuera del VPS y prueba restaurarlo en un volumen distinto.
Respaldar y restaurar la configuración de Portainer
El objetivo del respaldo de portainer_data es recuperar cuentas, conexiones y configuración del panel, no los datos de todas las cargas. Antes de copiar en frío, registra la imagen actual y detén el contenedor brevemente:
docker inspect portainer --format '{{.Config.Image}} {{.Image}}'
docker stop portainer
docker run --rm \
-v portainer_data:/source:ro \
-v "$PWD":/backup \
alpine:3.21 tar -czf /backup/portainer-data.tar.gz -C /source .
docker start portainer Comprueba que el archivo existe y muévelo a almacenamiento externo:
tar -tzf portainer-data.tar.gz | head
sha256sum portainer-data.tar.gz Para ensayar una restauración, crea un volumen nuevo y un contenedor de prueba enlazado solo a loopback. No sobrescribas el volumen operativo para descubrir si la copia funciona. Revisa además el mecanismo de respaldo incorporado disponible en tu versión, porque puede manejar metadatos de manera más adecuada.
Actualizar Portainer conservando rollback
Actualizar el contenedor no requiere borrar su volumen. Descarga la imagen seleccionada, conserva los datos y recrea únicamente Portainer:
docker pull portainer/portainer-ce:lts
docker stop portainer
docker rename portainer portainer-anterior
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
docker logs --tail=100 portainer Prueba inicio de sesión, visualización de endpoints y lectura de un stack. Si la nueva versión falla antes de migrar datos de forma irreversible, detén el nuevo contenedor y recupera el anterior. Por eso debes leer las notas: una migración del contenido del volumen puede impedir volver solo cambiando la imagen.
No elimines portainer-anterior ni la imagen previa hasta completar las pruebas. Tampoco confundas eliminar el contenedor antiguo con eliminar el volumen; usa nombres explícitos y revisa cada comando.
Errores frecuentes en Portainer
| Síntoma | Causa probable | Comprobación segura |
|---|---|---|
| 9443 no abre | Publicación, firewall o contenedor detenido | docker port, ss, docker logs |
| Advertencia TLS | Certificado autofirmado inicial | Usar proxy o certificado confiable |
| Endpoint local no disponible | Socket ausente o permisos | Inspeccionar montajes del contenedor |
| Stack falla al desplegar | YAML, variable o nombre ocupado | Validar Compose y revisar logs |
| Panel reinicia | Error de migración, disco o memoria | Estado, logs y kernel antes de recrear |
| Volumen no aparece en un stack | Nombre de proyecto o volumen externo | Comparar definición e inventario Docker |
| Aplicación funciona pero panel no | Portainer es plano de control separado | Reparar panel sin tocar la carga |
Cuándo usar Portainer y cuándo mantener la terminal
Portainer aporta valor cuando varias personas necesitan una vista común, pero la automatización debe seguir siendo reproducible fuera del panel. Para un solo administrador cómodo con Compose, la interfaz puede ser opcional. Para soporte y equipos junior, reduce la barrera para leer logs y estados, siempre que los permisos y procedimientos eviten cambios arbitrarios.
Mantén disponibles el acceso SSH, los archivos versionados y los comandos de recuperación. Si el panel es la única forma que el equipo conoce para operar, una avería de portainer_data se convierte innecesariamente en una avería de todas las aplicaciones.
Diseñar permisos y cambios con una identidad individual
El panel no debería convertir una cuenta compartida en la llave maestra de todos los VPS. Crea usuarios separados, asigna acceso solo a los entornos necesarios y revisa las capacidades disponibles en tu edición. Un técnico que solo consulta logs no necesita poder desplegar un contenedor privilegiado.
Mantén un proceso para altas, bajas y cambios de función. Cuando alguien deja el equipo, revoca su cuenta, sesiones, VPN y llaves SSH; desactivar solo Portainer no corta otros caminos administrativos. Si la autenticación se integra con un proveedor externo, prueba también qué ocurre cuando ese proveedor está caído y conserva una cuenta de recuperación protegida.
Antes de ejecutar cambios de riesgo, registra quién los solicitó, qué stack o contenedor se afecta y cómo se revierte. El historial de una interfaz no sustituye un ticket o commit que explique intención. Evita editar a la vez desde Portainer y desde docker compose en la terminal: la última recreación puede pisar el trabajo de la otra.
Auditar exposición y privilegios de los contenedores
Portainer facilita detectar configuraciones peligrosas si sabes qué buscar. Revisa puertos publicados, modo privilegiado, montajes del host y capacidades. Desde terminal puedes producir un inventario:
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}'
for id in $(docker ps -q); do
docker inspect "$id" \
--format '{{.Name}} privileged={{.HostConfig.Privileged}} network={{.HostConfig.NetworkMode}}'
done Busca contenedores que monten el socket Docker o directorios sensibles:
for id in $(docker ps -q); do
docker inspect "$id" \
--format '{{.Name}} {{range .Mounts}}{{.Source}}:{{.Destination}} {{end}}'
done Un montaje de /var/run/docker.sock puede estar justificado para Portainer, pero no para una aplicación web. Un montaje de / o /etc con escritura merece revisión inmediata. Corrige en la definición del stack y recrea; modificar el contenedor en caliente no cambia su configuración de arranque.
Recuperar acceso sin borrar portainer_data
Una contraseña olvidada o una cuenta inicial caducada no justifica eliminar el volumen. Consulta el procedimiento oficial correspondiente a tu versión para restablecer el administrador mediante la herramienta soportada y realiza una copia previa del volumen. No sigas comandos de imágenes auxiliares desconocidas que montan tus datos administrativos.
Si Portainer no arranca, inspecciona primero:
docker ps -a --filter name=portainer
docker logs --tail=300 portainer
docker inspect portainer --format '{{json .State}}'
docker volume inspect portainer_data
df -h Un puerto ocupado, disco lleno o migración fallida requiere soluciones distintas. Recrea el contenedor con la misma imagen y volumen únicamente después de registrar sus opciones; olvidar el socket o enlazar otro volumen puede producir un panel vacío que parece pérdida de datos.
Ensayar la administración cuando Portainer no está disponible
Las aplicaciones deben poder operarse desde Docker aunque el panel esté caído. Elige un stack de prueba y documenta cómo consultar su estado, logs, definición y volúmenes sin la interfaz.
docker ps --filter label=com.docker.compose.project
docker compose -f /opt/tienda/compose.yaml ps
docker compose -f /opt/tienda/compose.yaml logs --tail=100
docker volume ls Después recrea Portainer en otro puerto o host de prueba usando una copia de portainer_data. Confirma endpoints, usuarios y stacks. Este ejercicio separa el plano de control de las cargas y evita que un problema del panel provoque cambios innecesarios en contenedores sanos.
Supervisar el panel como servicio administrativo
Portainer necesita una comprobación propia aunque las aplicaciones continúen sin él. Vigila que el contenedor esté activo, que el panel responda desde la red de gestión y que el certificado no venza. No publiques una ruta de salud administrativa en internet solo para facilitar el monitor; ejecuta la prueba desde la VPN o el VPS.
docker inspect portainer --format '{{.State.Status}} {{.RestartCount}}'
curl -kfsS -o /dev/null https://127.0.0.1:9443/
docker logs --since=15m portainer -k es aceptable aquí únicamente para la prueba local del certificado autofirmado; el monitor público debe validar el certificado confiable del proxy. Alerta por reinicios repetidos y disco, no por un único fallo transitorio.
Define también una ventana de mantenimiento. Actualizar Portainer mientras otra persona despliega un stack mezcla dos cambios y dificulta atribuir el resultado. Comunica el inicio, conserva acceso por terminal y cierra con una prueba de endpoint y stack.
Incorporar contenedores existentes sin perder su definición
Portainer puede mostrar contenedores creados desde la terminal, pero verlos no convierte su configuración en un stack reproducible. Antes de migrar la operación, exporta o documenta imagen, variables, puertos, redes, montajes y política de reinicio.
docker inspect NOMBRE_CONTENEDOR > contenedor-inspect.json
docker inspect NOMBRE_CONTENEDOR \
--format '{{.Config.Image}} {{json .HostConfig.PortBindings}} {{json .Mounts}}' El JSON de inspección puede incluir variables secretas; guárdalo con permisos restrictivos y no lo subas al repositorio. Escribe después un compose.yaml sin secretos y valida la equivalencia en otro nombre o VPS de pruebas.
No “adoptes” producción recreando el contenedor desde el panel sin comprobar dónde están sus datos. Un volumen anónimo o un bind mount a una ruta del host puede quedar fuera de la nueva definición y producir una aplicación vacía.
Cuando la versión declarada funcione, decide una única vía de cambios. Si el stack vive en Git, edita y revisa allí; usa Portainer para desplegar e inspeccionar. Mantén el inspect original hasta verificar rutas, salud y persistencia después de una recreación.
Compartir evidencia de soporte sin filtrar secretos
Capturas del panel pueden mostrar nombres internos, registros, variables o rutas del host. Antes de enviarlas, reduce el incidente a estado, hora, imagen y mensaje concreto. Los archivos completos de docker inspect incluyen variables de entorno y no deben adjuntarse sin revisión.
docker inspect portainer \
--format 'image={{.Config.Image}} status={{.State.Status}} started={{.State.StartedAt}} restarts={{.RestartCount}}'
docker logs --since=15m --timestamps portainer Reemplaza tokens o dominios sensibles en la copia, no en los logs originales que conserva el equipo. Si un secreto apareció en un ticket externo, rótalo; ocultar luego el mensaje no garantiza que no quedaran copias.
Incluye pasos reproducibles y qué cambió justo antes. “Portainer no funciona” obliga a pedir información; un código, hora y prueba del puerto permiten localizar la capa sin dar acceso al VPS.
Instalar Portainer lleva pocos comandos; operarlo con seguridad exige limitar 9443 y proteger el socket Docker. Conserva el volumen, respalda aplicaciones por separado y no confundas interfaz sencilla con privilegios bajos.
Hosting con LiteSpeed, NVMe y soporte 24/7 desde $3/mes.