apps/web is the lightweight self-hosted web edition of PromptHub.
It is intended for personal use, home lab deployments, or small single-instance setups where users want browser access to their local-first PromptHub workspace without relying on the official cloud product.
It is not the hosted commercial PromptHub Cloud stack. Keep the boundary clear:
apps/web: self-hosted, simple auth, workspace files + SQLite index, user-managed deploymentprompthub-cloud: official hosted SaaS, team/billing/multi-tenant/cloud operations
This app provides browser-safe workspace capabilities:
- prompts, folders, prompt hierarchy, relations, and output-format sequences
- skill records, versions, safety review, import/export, and remote import
- rules, media, settings, immutable desktop backup, and legacy sync compatibility
MCP and Plugin data remains part of desktop backup and legacy synchronization payloads, but the browser does not manage or apply those Desktop-owned resources. The web workspace also does not expose local skill package files, agent scans, symlinks, platform installation, or native shell operations.
It should not grow cloud-only features such as:
- billing
- team workspaces
- multi-tenant organization management
- hosted object storage orchestration
- cloud admin operations
PromptHub Desktop can use this self-hosted web workspace as a personal backup and restore target.
In desktop Settings -> Data, configure:
- self-hosted PromptHub URL
- username
- password
Then the current desktop can:
- test the connection
- create a new immutable remote snapshot without changing the live Web workspace
- explicitly restore the latest verified snapshot after creating a local safety snapshot
- create an upload-only snapshot once on startup
- periodically create upload-only snapshots in the background
Desktop and Web versions must match exactly, and both sides must support the same backup protocol. A mismatch skips automatic backup and blocks manual backup/restore before local export or remote write. Automatic tasks never pull, merge, or replace local data.
Live automatic sync selects one of webdav or s3. Self-hosted Web backup is
independent from that selection, so it can create recovery snapshots while a
single live-sync provider remains active. The persisted provider type still
accepts self-hosted for old settings, but the current desktop normalizes that
legacy value to manual.
Authenticated backup routes live under /api/backups/desktop. The server keeps
up to ten checksummed snapshots per user under
DATA_ROOT/backups/desktop/<hashed-user>/. Snapshot files are immutable,
symbolic-link paths are rejected, and the live Web database/workspace is not
imported or changed. The request limit is 50 MiB.
The snapshot contains prompt graph data, Rules, full Skill files and versions, MCP/Plugin libraries and packages, store sources, Agent assets, inline media, and non-secret settings. Passwords, tokens, API keys, access keys, and proxy credentials are excluded because this channel is not encrypted as a secret vault.
Legacy web sync operations (PUT /sync/data, POST /sync/push, and
POST /sync/pull) remain available for older clients and return a unified
summary block (prompts, folders, rules, skills). The current desktop
UI and scheduler do not call these routes for self-hosted backup.
Complete snapshots also preserve prompt relations and output-format items. When an import skips a dangling dependency, the response includes imported/skipped counts so a desktop client can report a partial graph restore.
Incremental WebDAV/S3 downloads verify the manifest data hash and media hash/size before restoring local records. A mismatch or missing media file is a failed sync, not a partial successful restore.
When a new deployment starts with an empty database:
- The first visit goes to
/setup, not the login page. - The user creates the initial administrator account there.
- Public registration stays disabled after that first account is created.
Copy the example environment file first:
cp apps/web/.env.example apps/web/.envInstall dependencies from the repository root:
pnpm installImportant variables:
JWT_SECRET: required, at least 32 charactersAGENT_SECRET_KEY: optional 32-byte hex or base64 key. It is required before the Web Agent workspace can store Provider credentials or edit native Agent config files. Generate one withopenssl rand -hex 32, keep it stable, and back it up separately fromDATA_ROOT; losing it makes existing encrypted credentials and config rollback backups unreadable.DATA_ROOT: root directory for all PromptHub data (default:./). The app writesdata/,config/,logs/, andbackups/under this path.ALLOW_REGISTRATION=false: keep this disabled; the first admin is created only through/setupAUTH_CAPTCHA_ENABLED=true: keep image captcha enabled by default. For trusted private/LAN personal deployments, setAUTH_CAPTCHA_ENABLED=falseto remove setup/login captcha.TRUST_PROXY_HEADERS=false: keep this disabled unless your reverse proxy strips client-supplied forwarding headers and writes trustedX-Forwarded-For/X-Real-IPvalues.
PromptHub Web requires an image captcha on setup and login by default. This is the recommended setting for any public or internet-reachable deployment:
AUTH_CAPTCHA_ENABLED=trueFor trusted private/LAN personal deployments, you can explicitly disable the setup/login captcha:
AUTH_CAPTCHA_ENABLED=falseWhen disabled, /api/auth/bootstrap reports captchaEnabled: false, the setup/login pages hide the captcha field, and the server accepts register/login requests without captchaId or captchaAnswer. This switch does not change passwords, JWT cookies, registration policy, or auth rate limits.
pnpm dev:webDefault ports:
- client:
http://localhost:5174 - server:
http://localhost:3000
pnpm build:web
pnpm --filter @prompthub/web startUseful root-level commands:
pnpm lint:webpnpm typecheck:webpnpm test:web -- --runpnpm verify:webpnpm docker:web:build
apps/web already includes a production Dockerfile and ready-to-use compose files.
When a v<version> release tag is built in CI, PromptHub also publishes a
container image to GHCR:
ghcr.io/legeling/prompthub-web:<version>ghcr.io/legeling/prompthub-web:v<version>ghcr.io/legeling/prompthub-web:latestfor stable tags only
Prerelease tags such as v0.6.0-beta.1 publish their explicit versioned image
without moving latest. Use the explicit prerelease tag for manual beta
testing; production deployments that track latest remain on the latest
stable image.
cd apps/web
cp .env.example .envThen edit .env and set at least:
JWT_SECRET=replace-with-a-random-secret-at-least-32-chars
AGENT_SECRET_KEY=replace-with-the-output-of-openssl-rand-hex-32
ALLOW_REGISTRATION=false
AUTH_CAPTCHA_ENABLED=true
TRUST_PROXY_HEADERS=falseStart the service:
docker compose up -d --buildDefault access URL:
http://localhost:3871
The compose file mounts PromptHub-managed data roots so your database, workspace files, and uploaded media stay outside the container.
Each mounted DATA_ROOT must be used by one Web server process at a time. The
self-hosted entry point can recover a legacy SQLite lock left by a crashed or
pre-release process, but this is not multi-replica SQLite support; do not scale
multiple containers against the same data volume.
The latest alias below tracks stable releases only.
docker pull ghcr.io/legeling/prompthub-web:latest
docker run -d \
--name prompthub-web \
-p 3871:3000 \
-e JWT_SECRET='replace-with-a-random-secret-at-least-32-chars' \
-e AGENT_SECRET_KEY='replace-with-the-output-of-openssl-rand-hex-32' \
-e ALLOW_REGISTRATION=false \
-e AUTH_CAPTCHA_ENABLED=true \
-e TRUST_PROXY_HEADERS=false \
-v "$(pwd)/apps/web/data:/app/data" \
-v "$(pwd)/apps/web/config:/app/config" \
-v "$(pwd)/apps/web/backups:/app/backups" \
ghcr.io/legeling/prompthub-web:latestYou can also deploy directly from the published image with the compose override in apps/web.
If you deploy with Docker Compose:
cd apps/web
docker compose down
docker compose up -d --buildYour data remains intact as long as you keep the same mounted directories.
The safest backup strategy is to back up the entire DATA_ROOT, not only the SQLite file.
Typical persisted paths include:
data/prompthub.dbdata/prompts/...data/skills/...data/assets/...config/settings/...backups/...logs/...
- Back up
DATA_ROOTregularly. - Treat this app as a user-managed deployment artifact, not as a shared hosted service.
- If you expose it to the public internet, use HTTPS and a reverse proxy in front of it.
- Only set
TRUST_PROXY_HEADERS=truewhen that reverse proxy removes untrusted incoming forwarding headers; otherwise auth rate limits intentionally use a coarse fallback client bucket. - CI selects the self-hosted Web checks from the root verification registry, covering lint, typecheck, tests, production build, built-artifact smoke, Docker image build, and compose validation.