Por qué instalar Portainer en su VPS
Gestionar Docker desde la línea de comandos se vuelve rápidamente tedioso cuando usted acumula contenedores: encontrar los logs de un servicio, inspeccionar un volumen, reiniciar un stack o comprobar el uso de los recursos obliga a hacer malabares entre varios comandos. Portainer expone todo esto en una interfaz web: usted ve el estado de cada contenedor, consulta los logs en directo, abre una consola interactiva, despliega stacks mediante un editor de docker-compose y supervisa el consumo de CPU/RAM. A diferencia de un PaaS como CapRover o Dokku, Portainer no compila su código: es una herramienta de administración y de visualización de su entorno Docker existente. Es perfecto para los equipos que quieren un acceso claro y delegable a un servidor Docker sin dar acceso SSH a todo el mundo.
Lo que Portainer simplifica en el día a día
- Vista general en tiempo real de todos sus contenedores, imágenes, volúmenes y redes.
- Despliegue de stacks mediante un editor
docker-composeintegrado, sin tocar SSH. - Logs en directo y consola interactiva en cada contenedor, directamente en el navegador.
- Gestión detallada de los permisos: cree cuentas y equipos con accesos limitados.
- Supervisión del consumo de CPU, RAM y red de cada servicio.
- Gestión de varios hosts Docker o clústeres Swarm desde una sola interfaz.
Requisitos previos para Portainer
Portainer es extremadamente ligero porque solo administra Docker, sin builder ni base de datos pesada. Un VPS de 1 GB de RAM y 1 vCPU es de sobra suficiente para ejecutar el propio Portainer; dimensione después su VPS según las aplicaciones que piense alojar en él. Prevea de todos modos 20 GB de disco SSD para las imágenes Docker. Docker Engine debe estar instalado previamente (Portainer se conecta al socket /var/run/docker.sock). Se recomiendan un nombre de dominio portainer.midominio.com y un puerto 443 abierto para exponer la interfaz por HTTPS. Importante: Portainer da un control total sobre Docker, así que no deje nunca su interfaz directamente expuesta en Internet sin reverse proxy y sin autenticación fuerte. En cuanto a puertos, la documentación de instalación actual publica 9443 (interfaz HTTPS con certificado autofirmado); el puerto 8000 (túnel TCP) solo sirve para los agentes Edge y el 9000 (HTTP) es un puerto opcional heredado de versiones anteriores. Aquí solo abrimos el 9443, y únicamente mientras dura la configuración.
Desplegar Portainer en 5 pasos
Preparar Docker en el VPS
Instale Docker si aún no lo ha hecho:
curl -fsSL https://get.docker.com | sh. Compruébelo condocker ps. Cree un volumen dedicado para la persistencia de Portainer:docker volume create portainer_data.Lanzar el contenedor Portainer
Arranque Portainer CE:
docker run -d -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:lts. La documentación oficial de instalación usa la etiquetalts(soporte a largo plazo); es la que mantenemos para un servidor de producción, en lugar delatest. La interfaz queda accesible en el puerto 9443 con HTTPS autofirmado.Crear la cuenta de administrador
Lea primero el token de instalación en los registros:
docker logs portainer, líneasetup_token=. Desde las versiones 2.43 y 2.39.4, una instancia nueva lo exige para crear el primer administrador. Abra despuéshttps://IP_DE_SU_VPS:9443: la cuenta debe crearse en los 5 minutos posteriores al primer arranque; si no, Portainer se detiene por seguridad (mensaje «timed out for security purposes»). En ese caso,docker stop portainery luegodocker start portainerle dan otros 5 minutos. Elija una contraseña robusta (12 caracteres como mínimo).Exponer correctamente mediante un reverse proxy
Coloque Caddy o Nginx Proxy Manager delante de Portainer para servir la interfaz en
portainer.midominio.comcon un certificado Let's Encrypt real. Cierre después el acceso directo al puerto 9443. Atención: un puerto publicado por Docker esquiva las reglas deufw(Docker lo desvía antes de las cadenas que filtra ufw), así queufw deny 9443no basta. Vuelva a crear el contenedor con-p 127.0.0.1:9443:9443, de modo que solo el proxy local pueda alcanzarlo.Desplegar su primer stack
En el menú «Stacks», haga clic en «Add stack», pegue un archivo
docker-compose.ymlen el editor (por ejemplo una aplicación + PostgreSQL), dé un nombre al stack y haga clic en «Deploy the stack». Portainer crea los contenedores, la red y los volúmenes, y usted sigue su estado en tiempo real.
Active los «Access Controls» de Portainer para delegar la gestión de un stack concreto en un desarrollador sin darle acceso al conjunto del servidor. Para ir más lejos, despliegue un agente Portainer en un segundo VPS y vincúlelo a su instancia principal: administrará entonces varios servidores Docker desde un punto único. Haga copias de seguridad periódicas del volumen portainer_data, que contiene sus usuarios, endpoints y definiciones de stacks, así como las carpetas de los stacks procedentes de Git (compose/).
Desplegar desde Git con las actualizaciones GitOps
Pegar un archivo compose basta para empezar, pero un stack vinculado a un repositorio Git se actualiza solo y guarda su historial fuera de la interfaz. En «Stacks > Add stack», elija «Git Repository» y rellene después el origen, la referencia (rama) y la ruta del archivo compose. Portainer clona entonces el repositorio en su volumen de datos, bajo compose/<id del stack>. Este mecanismo, y solo este, es el que está en juego en la sección de solución de problemas que sigue.
Los ajustes que conviene conocer
- Origen, referencia y «Compose path»: el repositorio, la rama y la ruta del archivo compose desde la raíz; «Additional paths» fusiona otros archivos YAML, como varias opciones
-f. - «GitOps updates» por sondeo: Portainer comprueba el repositorio a intervalos regulares («Fetch interval»).
- «GitOps updates» por webhook: Portainer genera una URL que se llama desde su repositorio o una GitHub Action para lanzar la actualización a demanda.
- «Re-pull image»: vuelve a descargar las imágenes en cada actualización, como
--pull=always. - «Force redeployment»: vuelve a desplegar en cada intervalo o webhook, aunque el repositorio no haya cambiado, sobrescribiendo los cambios locales.
- Botón «Pull and redeploy» de la página del stack: obtiene el último commit y vuelve a desplegar de inmediato.
Solución de problemas: «Unable to move git repository directory: Target path already exists»
Síntoma exacto: en un stack desplegado desde Git, «Pull and redeploy» (o la actualización GitOps automática) falla con Unable to move git repository directory: Target path already exists, y los contenedores no se actualizan. Es la incidencia n.º 10428 del repositorio portainer/portainer, abierta en octubre de 2023 con Portainer CE 2.19.1 (repositorio privado de GitHub, nodo Edge), descrita como intermitente: un reinicio o esperar la hacía desaparecer a veces. Se sigue reportando en 2026.
Estado en la fuente, comprobado el 29 de octubre de 2026: la incidencia sigue abierta. Lleva las etiquetas de bug y de prioridad «2 - High», se asignó a un desarrollador de Portainer en julio de 2026 y su etiqueta de versión objetivo pasó de 3.0.0 a 3.1.0 en octubre de 2026. No tiene ninguna pull request vinculada, y la única corrección propuesta es un commit de un fork de un usuario que nunca se fusionó. No existe, por tanto, una corrección oficial a esta fecha: la solución alternativa de abajo sigue vigente y no debe esperar a una versión concreta para resolverlo.
Causas reportadas por los usuarios (hipótesis, no confirmadas por el editor)
- Una carpeta residual
<id>-oldencompose/: durante una actualización, Portainer parece renombrar la carpeta del stack a<id>-oldantes de mover el nuevo clon; si queda una de un intento anterior, el movimiento falla. - Un despliegue interrumpido: un contenedor Portainer bloqueado y reiniciado en pleno despliegue, o una página refrescada durante «Pull and redeploy», dejó el estado incoherente a varios usuarios (el mantenedor no pudo reproducirlo así).
- Imágenes voluminosas: el primer informante sospechaba un tiempo de espera agotado en un stack con una imagen de casi 2 GB.
- Variante de febrero de 2026: el error pasa a ser
stat /data/compose/61: no such file or directory, es decir, que la carpeta del stack ha desaparecido. La solución alternativa de abajo no ayuda en ese caso.
Solución alternativa prudente en 6 pasos
Localizar el stack y su identificador
Anote el nombre del stack que falla y su identificador numérico, que es el nombre de la carpeta
compose/<id>. No toque nunca la carpeta<id>en sí: solo se trata la carpeta<id>-old.Detener Portainer y respaldar el volumen
Detenga Portainer para congelar su base de datos:
docker stop portainer. Archive después todo el volumen:docker run --rm -v portainer_data:/data -v "$PWD":/backup alpine tar czf /backup/portainer_data-antes-del-arreglo.tgz -C /data .. Compruebe que el archivo existe y no está vacío antes de continuar.Listar la carpeta compose
Muestre su contenido:
docker run --rm -v portainer_data:/data alpine ls -la /data/compose. Busque una carpeta cuyo nombre sea el identificador del stack seguido de-old(por ejemplo61-old).Apartar la carpeta residual, sin borrarla
Muévala fuera del volumen:
docker run --rm -v portainer_data:/data -v "$PWD":/backup alpine mv /data/compose/61-old /backup/. Sustituya 61 por su identificador. Los usuarios informan de que borrar esta carpeta basta; apartarla da el mismo resultado y conserva una vía de vuelta atrás.Reiniciar y repetir la actualización
docker start portainery luego «Pull and redeploy» en el stack. Compruebe que los contenedores se han recreado de verdad con la nueva versión, y no solo que el mensaje de error ha desaparecido.Si el fallo persiste
Si no existe ninguna carpeta
-oldo si falta la carpeta<id>, esta solución alternativa no se aplica. La solución reportada es entonces eliminar y recrear el stack desde Git. Antes, compruebe que los datos de su aplicación están en volúmenes con nombre y respáldelos. Restaure el archivo del paso 2 solo si algo ha salido mal.
Prevención. Ninguna de estas medidas es una corrección garantizada, ya que el editor no ha confirmado la causa: solo reducen las ocasiones de dejar atrás una carpeta -old. No refresque la página ni reinicie Portainer durante un «Pull and redeploy». Descargue de antemano las imágenes voluminosas con docker pull para acortar el despliegue. Tras cada actualización fallida, compruebe de inmediato si queda una carpeta -old en compose/. Respalde portainer_data antes de actualizar Portainer. Para un servicio crítico, no dependa solo del botón de la interfaz: mantenga un despliegue de reserva con docker compose pull && docker compose up -d en el servidor. Siga la incidencia #10428 para saber cuándo llega una corrección.
Instalar Portainer desde el Marketplace ServOrbit
Todo lo anterior se hace a mano, y es útil saber hacerlo. Si prefiere no hacerlo, Portainer CE figura en el [Marketplace ServOrbit](/marketplace/despliegue-de-aplicaciones-devops/portainer) y se instala en su VPS con un solo clic. La plantilla despliega portainer/portainer-ce:latest en modo Docker Compose, monta el socket /var/run/docker.sock y crea el volumen portainer_data para la persistencia — sin sesión SSH para la configuración básica. La interfaz no se publica en Internet: la plantilla la enlaza a la dirección local del servidor (127.0.0.1, puerto HTTP 9000), de modo que se accede a ella mediante un túnel SSH o añadiendo un dominio personalizado desde su área de cliente. Al abrir la interfaz por primera vez, Portainer le guía mediante un asistente para crear su cuenta de administrador: si pide un token de instalación, está en los registros del contenedor (docker compose logs, línea setup_token=). Como toda plantilla del Marketplace, se entrega como guía de instalación, sin soporte de la aplicación en sí. Si prefiere quedarse en la rama de soporte a largo plazo, sustituya la etiqueta latest por lts en el archivo compose.