Documentación

Todo lo que necesitas para autoalojarlo.

PullPilot gestiona las actualizaciones de las imágenes y servicios Docker de tu homelab — estado, logs y modos de despliegue — desde una sola interfaz. Así lo pones en marcha y lo ajustas.

Instalación rápida

No necesitas .env si usas la ruta por defecto /srv/docker-stacks. El compose oficial define ALLOW_NO_AUTH=true para que el inicio rápido funcione en una LAN de confianza.

bash
$ sudo mkdir -p /srv/docker-stacks
$ mkdir -p ~/pullpilot && cd ~/pullpilot
$ curl -fsSL -o docker-compose.yml https://raw.githubusercontent.com/KN990x/PullPilot/main/docker-compose.yml
$ curl -fsSL -o .env.example https://raw.githubusercontent.com/KN990x/PullPilot/main/.env.example
$ docker compose up -d

Luego abre http://tu-servidor-ip:8000 (o el puerto de PULLPILOT_PORT).

Tras el arranque

Cada proyecto es una subcarpeta bajo la raíz de stacks con un docker-compose.yml (o docker-compose.yaml) dentro. Cuando puedas, mantén la carpeta de compose de PullPilot fuera de ese árbol.

/srv/docker-stacks/          # DOCKER_ROOT_PATH por defecto
├── plex/
   └── docker-compose.yml
├── uptime-kuma/
   └── docker-compose.yml
└── ...

Las carpetas llamadas pullpilot, pullpilot-ui, docker-updater y data se ignoran bajo la raíz de stacks.

Usar otra ubicación de stacks

Crea la carpeta en el host y añade un .env junto a docker-compose.yml apuntando a ella. La ruta debe ser idéntica en el host y dentro del contenedor, porque se monta uno a uno. Tras cualquier cambio en .env, ejecuta docker compose up -d (o docker compose restart).

.env
DOCKER_ROOT_PATH=/absolute/path/to/stacks

Guía de uso

Dashboard

Una tarjeta por proyecto — estado, actualización por proyecto e interruptores Full stop y Excluir.

Actualizar todo

Escanea los proyectos no excluidos, ejecuta git pull cuando aplica, recrea contenedores; resumen en el Historial.

Programación

Actualización global diaria por defecto a las 04:00 (hora del contenedor), o define la tuya por proyecto.

Variables de entorno

Una lista única para el .env de Compose. Copia .env.example y sobrescribe solo lo que necesites.

VariablePor defectoDescripción
DOCKER_ROOT_PATH/srv/docker-stacksMisma ruta absoluta de stacks en host y contenedor (bind mount).
PROJECTS_ROOT(de DOCKER_ROOT_PATH)Avanzado: úsala solo si la ruta dentro del contenedor debe diferir del bind mount.
PULLPILOT_PORT8000Puerto publicado en el host para la interfaz.
TZUTCZona horaria del contenedor.
DATA_DIR/app/dataSQLite y datos de ejecución (el compose oficial usa el volumen pullpilot_data).
ALLOW_NO_AUTHfalse**El compose oficial usa true. Si es false, AUTH_USER y AUTH_PASS son obligatorios o el arranque falla.
AUTH_USER / AUTH_PASSObligatorios cuando ALLOW_NO_AUTH=false. Si ambos están definidos, se exige sesión.
SESSION_SECRET(generado)Valor fijo ⇒ las sesiones sobreviven a reinicios. Obligatorio si UVICORN_WORKERS > 1. Genéralo con openssl rand -hex 32.
SESSION_HTTPS_ONLYfalsePon true si la app solo se sirve por HTTPS.
SESSION_SAME_SITElaxSameSite de la cookie: lax, strict o none. Usa none solo con HTTPS — los navegadores exigen Secure.
CORS_ORIGINS(vacío)Orígenes separados por comas. Vacío suele bastar cuando la SPA la sirve la propia app.
HEALTHCHECK_TIMEOUT60Espera de health tras el despliegue, en segundos.
COMMAND_TIMEOUT300Timeout de comandos externos, en segundos.
LOG_LOCALEesIdioma de los logs de actualizaciones programadas e historial (es o en). Las actualizaciones lanzadas desde la interfaz siguen Accept-Language.
LOGIN_RATE_LIMIT_ENABLEDtrueLímite de intentos de login en memoria, por IP.
LOGIN_RATE_LIMIT_MAX15Intentos máximos por ventana.
LOGIN_RATE_LIMIT_WINDOW_SEC300Duración de la ventana del límite, en segundos.
TRUST_X_FORWARDED_FORfalseUsa X-Forwarded-For para el límite de login. Actívalo solo detrás de un proxy de confianza.

Notas de seguridad

Trata PullPilot como acceso root — el socket de Docker está montado. No expongas el puerto 8000 a internet pública sin TLS, ALLOW_NO_AUTH=false, credenciales robustas y, a ser posible, otra capa de auth (Authelia, Authentik…).

Las actualizaciones y tareas programadas solo se ejecutan bajo la raíz de stacks resuelta. Las rutas fuera de ese árbol se rechazan.

Detrás de un proxy que termina TLS, define SESSION_HTTPS_ONLY=true, y define un SESSION_SECRET fijo para que las sesiones sobrevivan a reinicios.

Usa un solo worker de Uvicorn por instancia — el planificador y el límite de login viven en memoria. Si alguna vez subes UVICORN_WORKERS por encima de 1, tienes que definir SESSION_SECRET para que todos los workers compartan la misma clave de firma.

La imagen publicada es ghcr.io/kn990x/pullpilot. Si todavía apuntas a ghcr.io/kernel-nomad/pullpilot, actualiza tu compose — esa ruta ya no se mantiene.