Instalación rápida con Docker
Necesitas Docker Compose y un token de API de Cloudflare con permiso para editar Pages. Cinco comandos y el panel está en marcha:
mkdir easypages && cd easypages
curl -fsSL -o docker-compose.yml https://raw.githubusercontent.com/KN990x/EasyPages/main/docker-compose.yml
curl -fsSL -o .env.example https://raw.githubusercontent.com/KN990x/EasyPages/main/.env.example
cp .env.example .env
docker compose up -d --pull always
Edita .env antes del último comando: CF_API_TOKEN es la única variable obligatoria.
No hace falta clonar el repositorio. Compose descarga una imagen fijada en GHCR, monta
./easypages-data:/data y añade un healthcheck en /api/health. Tu cuenta y el secreto de
sesión viven en ese volumen. El contenedor corre como uid 1000, así que si creaste la carpeta
como root, ejecuta chown -R 1000:1000 ./easypages-data.
Después abre http://tu-servidor:8002.
El token de API de Cloudflare
Crea un token personalizado en Cloudflare Dashboard → My Profile → API Tokens con un único permiso:
Account→Cloudflare Pages→Edit
Con eso basta. No tienes que buscar tu account ID: se deduce del propio token, igual que
hacen el SDK oficial de Cloudflare y Wrangler. Solo tendrás que definir CF_ACCOUNT_ID si el
token da acceso a más de una cuenta, que es el único caso que la deducción no puede resolver
— los logs del servidor lo dicen y listan los identificadores entre los que elegir.
Crea tu cuenta
La primera vez que abras la aplicación verás el asistente de configuración. Crea tu cuenta enseguida.
No hay usuario ni contraseña en .env, y ninguna variable de entorno puede crear, sustituir ni
saltarse la cuenta. Hasta que la cuenta exista, cualquiera que llegue a ese puerto puede
crearla, así que no dejes una instancia recién levantada expuesta y sin atender. El modelo
completo está en SECURITY.md.
Variables de entorno
Solo la primera es obligatoria; el resto tiene un valor por defecto que funciona.
| Variable | Por defecto | Qué hace |
|---|---|---|
CF_API_TOKEN | — | Obligatoria. Token de API de Cloudflare con Cloudflare Pages: Edit. |
CF_ACCOUNT_ID | deducido | Solo si el token llega a más de una cuenta. |
EASYPAGES_DATA_DIR | /data | Dónde viven el fichero de credenciales y el secreto de sesión. Docker ya lo define. |
PORT | 8002 | Puerto en el que escucha el proceso Node. |
BIND_HOST | 127.0.0.1 | Interfaz de escucha. La imagen Docker pone 0.0.0.0 para que Compose publique el puerto. |
SESSION_COOKIE_SECURE | false | Ponlo a true si terminas HTTPS delante del contenedor. |
TRUST_PROXY | un salto | Ponlo a false si Node es alcanzable sin un proxy inverso de confianza delante. |
La lista de referencia es .env.example.
HTTPS y proxy inverso
Los datos de sesión van en una cookie firmada (easypages_sid), no en una carpeta de
sesión del servidor, así que escalar a varias réplicas no necesita sesiones pegajosas.
- HTTP plano (por defecto):
SESSION_COOKIE_SECURE=false, tal y como viene. - HTTPS terminado delante: pon
SESSION_COOKIE_SECURE=true. - Detrás de un proxy inverso: mantén el valor por defecto de
TRUST_PROXY(un salto de confianza para cabeceras reenviadas y límites de peticiones). - Node expuesto directamente: pon
TRUST_PROXY=false; de lo contrario el límite de peticiones se puede falsear con cabeceras reenviadas.
Ejecutar desde el código
Usa Node.js 24 o superior, la misma major que la imagen Docker y el CI de releases. Con
nvm, nvm use lo coge de .nvmrc.
corepack enable
pnpm install --frozen-lockfile
Crea .env a partir de .env.example con tu token de Cloudflare. Los datos locales
(credencial y secreto de sesión) van a ./data por defecto. Para una ejecución parecida a
producción:
pnpm run build
pnpm start
En desarrollo activo:
pnpm run dev— Express en el puerto8002(modo watch).pnpm run dev:ui— Vite en5173, con proxy de/api,/loginy/logoutahttp://localhost:8002.pnpm run lintypnpm test— ESLint y después las suites de backend (node:test) y frontend (vitest). Ejecuta antespnpm run build.
Hay un Makefile con los mismos objetivos: make setup, make dev, make lint, make test,
make clean-data.
¿Has perdido la contraseña?
No hay correo de recuperación. Detén la aplicación, borra el fichero de credenciales y arranca de nuevo: vuelve el asistente.
docker compose down
rm ./easypages-data/credentials.json
docker compose up -d
Con el repositorio clonado el fichero está en ./data/credentials.json, o ejecuta
make clean-data.
El modelo de seguridad, en corto
- Sin servidores de terceros. EasyPages habla directamente con la API de Cloudflare desde tu máquina.
- Tu token de API se queda en tu
.env, junto al contenedor. La cuenta de operador se guarda hasheada encredentials.jsondentro del volumen de datos. - Una única cuenta de operador, creada desde el navegador y guardada con hash en el volumen de datos.
- Cookie de sesión firmada, login con límite de intentos y tokens CSRF en cada petición que modifica algo.
- Apache-2.0: lee el código, audítalo, bifúrcalo.
El detalle completo, con la checklist de hardening y los límites conocidos, está en SECURITY.md.
Y a partir de aquí
- Repositorio — código, issues y releases.
- CONTRIBUTING.md — estructura del repositorio, límites arquitectónicos y proceso de release.
- Reportar un problema — errores y peticiones de funcionalidades.