Docker 部署 PromptHub:搭建个人 Prompt 与 AI 编程资产工作区
PromptHub Web 可以在浏览器中管理 Prompt、文件夹、Skill、Rules、媒体和部分 AI 配置,也可以作为 PromptHub Desktop 的自托管同步与备份目标。下面使用 v0.5.9 官方 GHCR 镜像,在单台主机上部署一个持久化的个人工作区。
PromptHub Web 面向个人、家庭实验室和小型单实例环境,不是 PromptHub Cloud 的私有化版本。Web 端不负责扫描本机 Skill、创建软链接、向 Claude Code 或 Codex 等本地工具安装文件,也不在浏览器中管理和应用桌面端拥有的 MCP、Plugin 资源。
部署结论
| 项目 | 本文采用的值 |
|---|---|
| GitHub 地址 | legeling/PromptHub |
| 官方镜像 | ghcr.io/legeling/prompthub-web:v0.5.9 |
| 项目版本 | v0.5.9 |
| 正式部署 | Docker Compose,使用官方 GHCR 固定版本镜像 |
| 快速体验 | 不提供:服务启动需要生成 JWT 密钥,并同时持久化数据库、工作区文件、配置和媒体 |
| 适用范围 | 个人自托管、家庭实验室、NAS 或可信内网中的单实例服务 |
| 主机架构 | linux/amd64;v0.5.9 GHCR 镜像未发布可运行的 linux/arm64 manifest |
| 最低资源 | 官方没有给出统一 CPU、内存和磁盘下限;磁盘容量取决于 Prompt、Skill、历史版本和媒体数量 |
| 对外端口 | 默认 127.0.0.1:3871 -> 3000 |
| 持久化位置 | ./data、./config、./logs、./backups 分别挂载到 /app 下的同名目录 |
| 依赖服务 | 无外部数据库或缓存;应用内置 SQLite |
| 验证范围 | 已确认 v0.5.9 发布和 GHCR 镜像清单;Compose 静态校验;未拉取镜像、未启动容器 |
| 部署日期 | 2026-09-03 |
Docker Compose 是这套部署的唯一主路径。固定镜像版本可以避免 latest 在重建容器时引入未经评估的迁移;四个绑定目录共同组成完整 DATA_ROOT,不能只备份 SQLite 文件。
运行结构与数据边界
浏览器和 PromptHub Desktop 都访问 PromptHub Web 的 3000 容器端口。服务端使用 SQLite 保存索引、用户和业务记录,同时把 Prompt、Skill、Rules、媒体和用户配置写入文件系统。
正在准备渲染...
查看源码
flowchart LR
Browser[浏览器] -->|127.0.0.1:3871| Web[PromptHub Web :3000]
Desktop[PromptHub Desktop] -->|Self-Hosted 同步| Web
Web --> DB[(data/prompthub.db)]
Web --> Workspace[data/prompts skills rules assets]
Web --> Config[config/settings devices]
Web --> Backups[backups]每个 DATA_ROOT 只能由一个 PromptHub Web 进程使用。SQLite 锁恢复机制用于处理异常退出留下的旧锁,不代表支持多副本;不要把多个容器连接到同一组 data 和 config 目录,也不要在前面配置会把请求分发到多个共享实例的负载均衡器。
部署前准备
主机需要安装 Docker Engine 和 Docker Compose v2:
docker --version
docker compose version
docker info --format '{{.Architecture}}'正式使用官方 v0.5.9 镜像时,最后一条命令应输出 x86_64 或 amd64。ARM64 主机可能出现 no matching manifest;当前文章没有验证 ARM64 源码构建,不能把模拟运行或未经测试的本地构建作为正式替代方案。
确认宿主机端口 3871 没有被占用:
ss -lntp | grep ':3871\b'没有输出通常表示端口空闲。已有监听者时,修改后文 .env 中的 PROMPTHUB_WEB_PORT,不要直接终止来源不明的进程。
Docker Compose 正式部署
创建目录和环境变量
mkdir -p "$HOME/apps/prompthub"/{data,config,logs,backups}
cd "$HOME/apps/prompthub"
umask 077
{
printf 'PROMPTHUB_WEB_PORT=3871\n'
printf 'JWT_SECRET=%s\n' "$(openssl rand -hex 32)"
printf 'JWT_ACCESS_TTL=900\n'
printf 'JWT_REFRESH_TTL=604800\n'
printf 'ALLOW_REGISTRATION=false\n'
printf 'AUTH_CAPTCHA_ENABLED=true\n'
printf 'TRUST_PROXY_HEADERS=false\n'
printf 'LOG_LEVEL=info\n'
} > .env
chmod 600 .envJWT_SECRET 必须至少 32 个字符。上面的命令生成 64 位十六进制随机值,并通过 umask 和 chmod 限制 .env 读取权限。不要把生成后的 .env 提交到 Git、发送到聊天或放进截图。
保持 ALLOW_REGISTRATION=false 不会阻止空数据库创建首个管理员;首次初始化通过 /setup 完成。公网或不可信网络应保留验证码,只有可信的个人局域网部署才考虑把 AUTH_CAPTCHA_ENABLED 改为 false。
创建 compose.yaml
将下面内容保存为 $HOME/apps/prompthub/compose.yaml:
name: prompthub
services:
web:
image: ghcr.io/legeling/prompthub-web:v0.5.9
container_name: prompthub-web
restart: unless-stopped
ports:
- "127.0.0.1:${PROMPTHUB_WEB_PORT:-3871}:3000"
environment:
HOST: 0.0.0.0
PORT: 3000
DATA_ROOT: /app
JWT_SECRET: ${JWT_SECRET:?JWT_SECRET is required}
JWT_ACCESS_TTL: ${JWT_ACCESS_TTL:-900}
JWT_REFRESH_TTL: ${JWT_REFRESH_TTL:-604800}
ALLOW_REGISTRATION: ${ALLOW_REGISTRATION:-false}
AUTH_CAPTCHA_ENABLED: ${AUTH_CAPTCHA_ENABLED:-true}
TRUST_PROXY_HEADERS: ${TRUST_PROXY_HEADERS:-false}
LOG_LEVEL: ${LOG_LEVEL:-info}
volumes:
- ./data:/app/data
- ./config:/app/config
- ./logs:/app/logs
- ./backups:/app/backups
healthcheck:
test:
- CMD
- node
- -e
- >-
fetch('http://127.0.0.1:3000/health')
.then((response) => process.exit(response.ok ? 0 : 1))
.catch(() => process.exit(1))
interval: 30s
timeout: 5s
start_period: 15s
retries: 3
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"官方 Compose 分别挂载 data、config 和 logs。PromptHub 的运行时布局还包含 /app/backups,因此正式配置一并持久化该目录。数据库位于 data/prompthub.db;Prompt、Skill、Rules 和媒体也保存在 data 子目录,用户设置与设备记录位于 config。
端口默认只绑定 127.0.0.1。同机浏览器可以直接访问,局域网或公网接入应先完成防火墙和 HTTPS 入口设计,再调整监听地址。
校验并启动
cd "$HOME/apps/prompthub"
docker compose config
docker compose pull
docker compose up -d
docker compose psdocker compose config 应输出规范化配置且没有缺少 JWT_SECRET 的错误。启动后 docker compose ps 中的 prompthub-web 应处于 running,健康状态经过启动窗口后应变为 healthy。
查看有界日志:
docker compose logs --tail=100 web日志不应持续出现环境变量校验失败、SQLite 无法打开、目录不可写或重复重启。
首次初始化与基本使用
创建首个管理员
浏览器打开:
http://127.0.0.1:3871/setup空数据库的第一次访问会进入 /setup。用户名长度为 3~50 个字符,只能包含字母、数字、下划线和连字符;密码至少 8 个字符。第一个账号具有管理员角色,创建完成后使用登录页面进入工作区。
保持 ALLOW_REGISTRATION=false 可以阻止初始化后的公开注册。如果页面没有进入 /setup,先用下面的接口确认数据库是否已经存在用户:
curl -fsS http://127.0.0.1:3871/api/auth/bootstrap响应会包含初始化状态和 captchaEnabled。不要通过删除 data/prompthub.db 重新初始化;这会丢失现有账号和业务数据。
创建和组织 Prompt
进入 Prompt 工作区后完成一次基础验收:
- 新建文件夹,例如“开发工具”。
- 新建名为“代码审查”的 Prompt,分别填写 System Prompt 和 User Prompt。
- 在 User Prompt 中加入
变量。 - 保存后复制或测试 Prompt,确认界面会要求填写
language。 - 为 Prompt 添加标签并创建一次修改,确认版本历史可以查看差异。
这组操作同时覆盖数据库记录、Prompt 文件树和版本数据,比只打开首页更能说明工作区已经可用。
管理 Skill 与 Rules
Web 端可以创建、导入、导出和查看 Skill、Rules,并参与桌面端同步。浏览器环境不能扫描宿主机目录,也不能把 SKILL.md 直接安装到 Claude Code、Cursor、Codex 等工具目录;平台安装、软链接和本地 Agent 扫描需要在 PromptHub Desktop 中完成。
MCP 和 Plugin 数据可以包含在完整备份与同步载荷中,但 v0.5.9 Web 界面不负责管理或应用这些桌面端资源。不要把 Web 端视为桌面版全部本地能力的浏览器替代品。
连接 PromptHub Desktop
在 PromptHub Desktop 中打开“设置 → 数据 → Self-Hosted PromptHub”,填写:
- URL:同机使用
http://127.0.0.1:3871;其他设备使用受控局域网地址或 HTTPS 域名。 - 用户名和密码:使用刚创建的 PromptHub Web 账号。
先执行“测试连接”,再根据数据方向选择把桌面工作区上传到 Web,或从 Web 下载并恢复到桌面端。确认手动同步方向和数据结果后,再启用启动时自动拉取或后台定时推送。
PromptHub Desktop 只允许一个活动同步源驱动自动同步。WebDAV、Self-Hosted PromptHub、S3 等多个来源同时自动写入会增加覆盖和冲突风险。
验证部署结果
下面的命令是目标主机验收步骤。当前文章没有启动容器,预期结果不能视为本次环境的运行记录。
应用与健康状态
curl -fsS http://127.0.0.1:3871/health
docker inspect -f '{{.State.Health.Status}}' prompthub-web健康接口应返回包含 "status":"ok" 和 "version":"0.5.9" 的 JSON,容器健康状态应为 healthy。
初始化与认证状态
curl -fsS http://127.0.0.1:3871/api/auth/bootstrap
docker compose logs --tail=100 web创建管理员前,接口应表示需要初始化;创建完成后应转为登录状态。日志不应包含连续的认证异常、数据库锁错误或请求失败。
持久化
先在界面创建“代码审查”测试 Prompt,再重建应用容器:
cd "$HOME/apps/prompthub"
docker compose up -d --force-recreate web
docker compose ps重新登录后,“代码审查”Prompt、文件夹、标签和版本历史应仍然存在。随后检查宿主机数据目录:
find data config -maxdepth 3 -type f | sort | head -50目录中应包含 data/prompthub.db 以及 Prompt、配置等文件。只看到容器为 healthy 不能证明数据已经持久化。
桌面端同步
使用测试 Prompt 验证双向同步:
- 在桌面端上传当前工作区,确认 Web 页面出现对应内容。
- 在 Web 页面修改测试 Prompt,再从桌面端拉取。
- 核对 Prompt 内容、文件夹、Rules、Skill 和媒体数据是否符合预期。
- 使用非关键测试数据确认恢复方向后,再同步正式工作区。
同步成功提示不能代替内容核对。上传与下载方向选错可能覆盖较新的工作区,应先创建备份。
日常运维
cd "$HOME/apps/prompthub"
docker compose ps
docker compose logs --tail=200 web
docker compose restart web
docker stats prompthub-web
du -sh data config logs backups查看当前镜像和健康信息:
docker compose images
docker inspect -f 'image={{.Config.Image}} health={{.State.Health.Status}} restarts={{.RestartCount}}' prompthub-web重启和升级前先确认没有桌面端同步、导入、媒体上传或 Prompt 编辑正在执行。
备份与恢复
PromptHub 官方建议备份完整 DATA_ROOT,不能只复制 data/prompthub.db。数据库以外还存在 Prompt 文件、Skill 文件、Rules、媒体、用户设置和设备记录。
创建一致性备份
先停止写入,再停止容器:
cd "$HOME/apps/prompthub"
docker compose stop web
mkdir -p backups
BACKUP_FILE="backups/prompthub-$(date +%F-%H%M%S).tar.gz"
tar --exclude='./backups' -czf "$BACKUP_FILE" \
compose.yaml .env data config logs
tar -tzf "$BACKUP_FILE" | head -50
docker compose start web归档包含 .env 中的 JWT 密钥,应按敏感备份管理。把备份复制到另一台主机或受控对象存储,记录校验和,并定期执行恢复演练;与运行目录位于同一磁盘的单份归档不能抵御磁盘故障。
恢复到独立目录
恢复前停止原服务,避免两个实例同时使用端口或同一数据目录:
cd "$HOME/apps/prompthub"
docker compose stop web
BACKUP_FILE="$(ls -1t "$HOME/apps/prompthub"/backups/prompthub-*.tar.gz | head -1)"
test -n "$BACKUP_FILE"
RESTORE_DIR="$HOME/apps/prompthub-restore-$(date +%F-%H%M%S)"
mkdir -p "$RESTORE_DIR"
tar -xzf "$BACKUP_FILE" -C "$RESTORE_DIR"
cd "$RESTORE_DIR"
docker compose config
docker compose up -d
curl -fsS http://127.0.0.1:3871/health登录恢复实例,核对管理员账号、Prompt、版本历史、Skill、Rules、媒体和设置。确认恢复完整前保留原目录,不要删除原数据库。验收完成后再决定是否把恢复目录作为新的正式目录。
升级与回滚
升级前查看目标版本发布说明和 Web 自托管文档,确认镜像标签、数据布局和迁移要求。单实例 SQLite 服务没有滚动升级能力,应安排短暂停机窗口。
cd "$HOME/apps/prompthub"
docker compose images
docker compose stop web按上一节创建完整离线备份,然后把 compose.yaml 中的镜像标签改为已经核对的目标版本:
docker compose config
docker compose pull
docker compose up -d
docker compose ps
curl -fsS http://127.0.0.1:3871/health升级后验证登录、Prompt 读写、版本历史、Skill、Rules、媒体和桌面端同步。不要把 latest 用作长期部署标签;重新创建容器时,latest 可能指向尚未完成迁移评估的新版本。
回滚不仅是把镜像标签改回 v0.5.9。如果新版本已经修改数据库或文件布局,旧版本可能无法读取升级后的数据;应停止新版本,恢复升级前的 Compose、.env 和完整数据归档,再执行登录和内容验收。
公网与反向代理配置
默认的 127.0.0.1:3871 适合本机或由同机反向代理访问。局域网直接访问需要把端口映射改为受控网卡地址,例如:
ports:
- "192.168.1.10:3871:3000"不要直接使用无防火墙限制的 0.0.0.0:3871 暴露到公网。公网部署应在 PromptHub Web 前配置 HTTPS 反向代理,并保持 AUTH_CAPTCHA_ENABLED=true。
只有反向代理会删除客户端提交的 Forwarded、X-Forwarded-For、X-Real-IP 和 X-Forwarded-Proto,再写入可信值时,才能设置:
TRUST_PROXY_HEADERS=truePromptHub 使用 X-Forwarded-Proto: https 判断代理后的请求是否安全,并据此给认证 Cookie 增加 Secure 属性和返回 HSTS。错误信任客户端伪造的转发头会削弱认证限流和安全请求判断。
安全边界
JWT_SECRET用于签发访问与刷新令牌。更换密钥会使现有登录会话失效;密钥泄露时应立即轮换并重新登录。- PromptHub Web 默认启用图形验证码和认证速率限制。可信个人局域网以外不要关闭验证码。
ALLOW_REGISTRATION=false应保持关闭。首管理员通过/setup创建,不需要临时开放公开注册。- Prompt、Skill、Rules、媒体、AI 服务配置和备份可能包含敏感业务数据。限制部署目录、Docker daemon 和备份存储的访问权限。
- 第三方 AI API Key、GitHub Token、WebDAV 或 S3 凭据不要写进 Compose、Git 仓库、日志和截图。通过产品设置保存凭据前,应确认目标环境和备份范围符合组织策略。
- PromptHub Web 是个人单实例应用,不提供 PromptHub Cloud 的团队、计费、多租户隔离和云端运维能力。
- 官方
v0.5.9GHCR 镜像当前只有linux/amd64应用 manifest。ARM 主机不要依赖透明模拟承载重要数据和长期服务。
常见问题
容器启动后反复退出
先查看最近日志和 Compose 展开结果:
docker compose logs --tail=200 web
docker compose config如果日志显示 JWT_SECRET must be at least 32 characters,重新运行 openssl rand -hex 32,把输出写入 .env 的 JWT_SECRET,再执行 docker compose up -d。不要使用文章中的固定示例字符串作为正式密钥。
ARM64 主机无法拉取镜像
确认主机和镜像架构:
docker info --format '{{.Architecture}}'
docker buildx imagetools inspect ghcr.io/legeling/prompthub-web:v0.5.9v0.5.9 官方镜像当前只有 linux/amd64。ARM64 主机应等待官方多架构镜像,或在独立测试环境从匹配版本源码构建并完成数据库、媒体、备份恢复和升级验证;不要把 --platform linux/amd64 模拟运行直接视为生产支持。
重建容器后数据消失
检查实际挂载:
docker inspect prompthub-web --format '{{json .Mounts}}'
ls -la data config backupsCompose 必须把宿主机 data、config、logs、backups 分别挂载到 /app 下的同名路径,并保持 DATA_ROOT=/app。如果曾在没有挂载的情况下写入数据,旧数据只存在于旧容器可写层;删除旧容器前先确认能否导出。
首次访问没有进入 setup 页面
curl -fsS http://127.0.0.1:3871/api/auth/bootstrap
find data -maxdepth 2 -type f -ls已有 data/prompthub.db 通常表示目录不是全新部署,应用会进入登录流程。确认挂载目录是否选错,或使用现有管理员登录。不要删除数据库绕过认证;忘记凭据时应从已验证备份恢复。
反向代理后登录异常或频繁触发限流
确认 HTTPS 代理是否覆盖而不是追加客户端传入的转发头,并检查上游是否发送 X-Forwarded-Proto: https。只有满足该条件才启用 TRUST_PROXY_HEADERS=true;修改后重建容器并清除站点旧 Cookie,再重新登录。
SQLite 报锁定或服务间歇失败
docker ps --filter name=prompthub-web
docker compose logs --tail=200 web确认没有第二个 PromptHub Web 容器、旧 Compose 项目或宿主机进程连接同一 DATA_ROOT。一个数据目录只允许一个 Web 服务进程使用;增加容器副本不会提高可用性,反而会造成 SQLite 和文件工作区并发写入风险。
部署完成后
完成首管理员、测试 Prompt、容器重建持久化和桌面端双向同步验收后,再安排 HTTPS、异机备份和定期恢复演练。正式导入大量 Prompt、Skill、Rules 或媒体前,先确认同步方向和备份能够恢复。
总结
PromptHub v0.5.9 可以通过单个 Docker Compose 服务提供浏览器工作区和桌面端同步目标。可靠运行依赖固定版本镜像、强 JWT 密钥、完整 DATA_ROOT 持久化、单实例 SQLite 约束和经过验证的备份恢复流程。
当前 GHCR 镜像适用于 linux/amd64,文章只完成镜像清单核验和 Compose 静态校验。目标主机仍需执行健康检查、首管理员创建、真实内容读写、容器重建和桌面端同步,才能确认部署链路满足实际使用要求。
参考资料
- https://github.com/legeling/PromptHub
- https://github.com/legeling/PromptHub/releases/tag/v0.5.9
- https://github.com/legeling/PromptHub/blob/v0.5.9/docs/web-self-hosted.md
- https://github.com/legeling/PromptHub/blob/v0.5.9/apps/web/docker-compose.yml
- https://github.com/legeling/PromptHub/blob/v0.5.9/apps/web/docker-compose.ghcr.yml
- https://github.com/legeling/PromptHub/blob/v0.5.9/apps/web/.env.example
- https://github.com/legeling/PromptHub/blob/v0.5.9/apps/web/Dockerfile
- https://github.com/legeling/PromptHub/blob/v0.5.9/.github/workflows/web-self-hosted.yml