Skip to content

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/amd64v0.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、媒体和用户配置写入文件系统。

Mermaid 流程图
查看源码
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 锁恢复机制用于处理异常退出留下的旧锁,不代表支持多副本;不要把多个容器连接到同一组 dataconfig 目录,也不要在前面配置会把请求分发到多个共享实例的负载均衡器。

部署前准备

主机需要安装 Docker Engine 和 Docker Compose v2:

bash
docker --version
docker compose version
docker info --format '{{.Architecture}}'

正式使用官方 v0.5.9 镜像时,最后一条命令应输出 x86_64amd64。ARM64 主机可能出现 no matching manifest;当前文章没有验证 ARM64 源码构建,不能把模拟运行或未经测试的本地构建作为正式替代方案。

确认宿主机端口 3871 没有被占用:

bash
ss -lntp | grep ':3871\b'

没有输出通常表示端口空闲。已有监听者时,修改后文 .env 中的 PROMPTHUB_WEB_PORT,不要直接终止来源不明的进程。

Docker Compose 正式部署

创建目录和环境变量

bash
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 .env

JWT_SECRET 必须至少 32 个字符。上面的命令生成 64 位十六进制随机值,并通过 umaskchmod 限制 .env 读取权限。不要把生成后的 .env 提交到 Git、发送到聊天或放进截图。

保持 ALLOW_REGISTRATION=false 不会阻止空数据库创建首个管理员;首次初始化通过 /setup 完成。公网或不可信网络应保留验证码,只有可信的个人局域网部署才考虑把 AUTH_CAPTCHA_ENABLED 改为 false

创建 compose.yaml

将下面内容保存为 $HOME/apps/prompthub/compose.yaml

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 分别挂载 dataconfiglogs。PromptHub 的运行时布局还包含 /app/backups,因此正式配置一并持久化该目录。数据库位于 data/prompthub.db;Prompt、Skill、Rules 和媒体也保存在 data 子目录,用户设置与设备记录位于 config

端口默认只绑定 127.0.0.1。同机浏览器可以直接访问,局域网或公网接入应先完成防火墙和 HTTPS 入口设计,再调整监听地址。

校验并启动

bash
cd "$HOME/apps/prompthub"
docker compose config
docker compose pull
docker compose up -d
docker compose ps

docker compose config 应输出规范化配置且没有缺少 JWT_SECRET 的错误。启动后 docker compose ps 中的 prompthub-web 应处于 running,健康状态经过启动窗口后应变为 healthy

查看有界日志:

bash
docker compose logs --tail=100 web

日志不应持续出现环境变量校验失败、SQLite 无法打开、目录不可写或重复重启。

首次初始化与基本使用

创建首个管理员

浏览器打开:

text
http://127.0.0.1:3871/setup

空数据库的第一次访问会进入 /setup。用户名长度为 3~50 个字符,只能包含字母、数字、下划线和连字符;密码至少 8 个字符。第一个账号具有管理员角色,创建完成后使用登录页面进入工作区。

保持 ALLOW_REGISTRATION=false 可以阻止初始化后的公开注册。如果页面没有进入 /setup,先用下面的接口确认数据库是否已经存在用户:

bash
curl -fsS http://127.0.0.1:3871/api/auth/bootstrap

响应会包含初始化状态和 captchaEnabled。不要通过删除 data/prompthub.db 重新初始化;这会丢失现有账号和业务数据。

创建和组织 Prompt

进入 Prompt 工作区后完成一次基础验收:

  1. 新建文件夹,例如“开发工具”。
  2. 新建名为“代码审查”的 Prompt,分别填写 System Prompt 和 User Prompt。
  3. 在 User Prompt 中加入 变量。
  4. 保存后复制或测试 Prompt,确认界面会要求填写 language
  5. 为 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 等多个来源同时自动写入会增加覆盖和冲突风险。

验证部署结果

下面的命令是目标主机验收步骤。当前文章没有启动容器,预期结果不能视为本次环境的运行记录。

应用与健康状态

bash
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

初始化与认证状态

bash
curl -fsS http://127.0.0.1:3871/api/auth/bootstrap
docker compose logs --tail=100 web

创建管理员前,接口应表示需要初始化;创建完成后应转为登录状态。日志不应包含连续的认证异常、数据库锁错误或请求失败。

持久化

先在界面创建“代码审查”测试 Prompt,再重建应用容器:

bash
cd "$HOME/apps/prompthub"
docker compose up -d --force-recreate web
docker compose ps

重新登录后,“代码审查”Prompt、文件夹、标签和版本历史应仍然存在。随后检查宿主机数据目录:

bash
find data config -maxdepth 3 -type f | sort | head -50

目录中应包含 data/prompthub.db 以及 Prompt、配置等文件。只看到容器为 healthy 不能证明数据已经持久化。

桌面端同步

使用测试 Prompt 验证双向同步:

  1. 在桌面端上传当前工作区,确认 Web 页面出现对应内容。
  2. 在 Web 页面修改测试 Prompt,再从桌面端拉取。
  3. 核对 Prompt 内容、文件夹、Rules、Skill 和媒体数据是否符合预期。
  4. 使用非关键测试数据确认恢复方向后,再同步正式工作区。

同步成功提示不能代替内容核对。上传与下载方向选错可能覆盖较新的工作区,应先创建备份。

日常运维

bash
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

查看当前镜像和健康信息:

bash
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、媒体、用户设置和设备记录。

创建一致性备份

先停止写入,再停止容器:

bash
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 密钥,应按敏感备份管理。把备份复制到另一台主机或受控对象存储,记录校验和,并定期执行恢复演练;与运行目录位于同一磁盘的单份归档不能抵御磁盘故障。

恢复到独立目录

恢复前停止原服务,避免两个实例同时使用端口或同一数据目录:

bash
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 服务没有滚动升级能力,应安排短暂停机窗口。

bash
cd "$HOME/apps/prompthub"
docker compose images
docker compose stop web

按上一节创建完整离线备份,然后把 compose.yaml 中的镜像标签改为已经核对的目标版本:

bash
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 适合本机或由同机反向代理访问。局域网直接访问需要把端口映射改为受控网卡地址,例如:

yaml
ports:
  - "192.168.1.10:3871:3000"

不要直接使用无防火墙限制的 0.0.0.0:3871 暴露到公网。公网部署应在 PromptHub Web 前配置 HTTPS 反向代理,并保持 AUTH_CAPTCHA_ENABLED=true

只有反向代理会删除客户端提交的 ForwardedX-Forwarded-ForX-Real-IPX-Forwarded-Proto,再写入可信值时,才能设置:

env
TRUST_PROXY_HEADERS=true

PromptHub 使用 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.9 GHCR 镜像当前只有 linux/amd64 应用 manifest。ARM 主机不要依赖透明模拟承载重要数据和长期服务。

常见问题

容器启动后反复退出

先查看最近日志和 Compose 展开结果:

bash
docker compose logs --tail=200 web
docker compose config

如果日志显示 JWT_SECRET must be at least 32 characters,重新运行 openssl rand -hex 32,把输出写入 .envJWT_SECRET,再执行 docker compose up -d。不要使用文章中的固定示例字符串作为正式密钥。

ARM64 主机无法拉取镜像

确认主机和镜像架构:

bash
docker info --format '{{.Architecture}}'
docker buildx imagetools inspect ghcr.io/legeling/prompthub-web:v0.5.9

v0.5.9 官方镜像当前只有 linux/amd64。ARM64 主机应等待官方多架构镜像,或在独立测试环境从匹配版本源码构建并完成数据库、媒体、备份恢复和升级验证;不要把 --platform linux/amd64 模拟运行直接视为生产支持。

重建容器后数据消失

检查实际挂载:

bash
docker inspect prompthub-web --format '{{json .Mounts}}'
ls -la data config backups

Compose 必须把宿主机 dataconfiglogsbackups 分别挂载到 /app 下的同名路径,并保持 DATA_ROOT=/app。如果曾在没有挂载的情况下写入数据,旧数据只存在于旧容器可写层;删除旧容器前先确认能否导出。

首次访问没有进入 setup 页面

bash
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 报锁定或服务间歇失败

bash
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 静态校验。目标主机仍需执行健康检查、首管理员创建、真实内容读写、容器重建和桌面端同步,才能确认部署链路满足实际使用要求。

参考资料

全部公开文章由同一个站点构建和发布。