# CreatorHub 部署 本文档适用于当前阶段 A:在一台 Linux 主机上通过 Docker Compose 部署。开发阶段不设访问限制,安全由部署者自行把控。 ## 部署内容 `compose.yaml` 会启动以下服务: - `creator-hub`:Go 1.26 控制面,同时提供 React 19/Vite 8 构建的静态页面; - `docker-gateway`:受限 Docker API 网关,是唯一挂载 `/var/run/docker.sock` 的服务; - `postgres`:PostgreSQL 17,数据保存在 `creatorhub_postgres` 命名卷; - 浏览器容器:由网关按需创建,使用固定摘要的指纹浏览器镜像,Profile 保存在 `creatorhub-profile-<运行时名称>` 命名卷。 控制面发布到宿主机所有网卡,局域网内可直接访问;浏览器容器可访问外网。 `creator-hub` 会等待 `docker-gateway` 健康检查通过后再启动。 ## 前置条件 - Linux 主机; - Docker Engine 26 或兼容版本; - Docker Compose v2; - 当前用户可访问 Docker daemon; - 可访问 `git.ipao.vip`,并已完成私有镜像仓库登录(如仓库要求认证); - `curl`,用于部署后检查。 在仓库根目录执行预检: ```bash test -S /var/run/docker.sock docker info >/dev/null docker compose version docker compose config --quiet ``` ## 首次部署 以下命令应在同一个 shell、仓库根目录执行。`DOCKER_GID` 必须与宿主机 Docker socket 的组一致;`CREATORHUB_PORT` 控制控制面的宿主机端口。 ```bash export DOCKER_GID="$(stat -c '%g' /var/run/docker.sock)" export CREATORHUB_PORT=8080 docker pull git.ipao.vip/rogee/fingerprint-chromium@sha256:b9f23b8e3ac640174db0dfa49e9095fe7eb06f5db55a4e7550d979b35ff3a1b7 docker compose config --quiet docker compose up --detach --build ``` 控制面启动时会连接 PostgreSQL,并在事务和 advisory lock 保护下自动执行前向迁移。迁移失败时控制面会退出,由 Compose 按 `restart: unless-stopped` 重启;先检查日志,不要删除数据卷。 ## 部署验证 ```bash curl --fail --silent --show-error \ --retry 30 --retry-delay 2 --retry-connrefused \ --output /dev/null "http://127.0.0.1:${CREATORHUB_PORT}/healthz" curl --fail --silent --show-error \ --retry 30 --retry-delay 2 --retry-connrefused \ "http://127.0.0.1:${CREATORHUB_PORT}/api/browsers" >/dev/null docker compose exec -T postgres \ psql -U creatorhub -d creatorhub -tAc \ 'SELECT 1 FROM schema_migration WHERE version = 1;' \ | grep -qx 1 docker compose ps ``` 健康检查应成功,浏览器列表接口应返回 JSON,迁移查询当前应输出 `1`,三个 Compose 服务应为运行状态。然后访问 ;修改过 `CREATORHUB_PORT` 时使用对应端口。 排障时读取结构化服务日志: ```bash docker compose logs --tail=200 creator-hub docker-gateway postgres ``` ## 配置 Compose 部署时通常只需设置以下宿主机变量: | 变量 | 默认值 | 说明 | | --- | --- | --- | | `CREATORHUB_PORT` | `8080` | 控制面宿主机端口,局域网可访问 | | `DOCKER_GID` | `999` | Docker socket 的宿主机组 ID;必须按实际值设置 | 服务本身支持并校验以下环境变量;`compose.yaml` 已提供当前部署所需的值: | 服务 | 变量 | 当前 Compose 值 | | --- | --- | --- | | `creator-hub` | `LISTEN_ADDR` | 默认 `:8080` | | `creator-hub` | `DOCKER_GATEWAY_URL` | `http://docker-gateway:8081` | | `creator-hub` | `WEB_DIR` | 镜像内固定为 `/app/web` | | `creator-hub` | `DATABASE_URL` | `postgres://creatorhub@postgres/creatorhub?sslmode=disable` | | `creator-hub` | `LOG_LEVEL` | 默认 `info` | | `docker-gateway` | `LISTEN_ADDR` | 默认 `:8081` | | `docker-gateway` | `DOCKER_SOCKET` | 默认值和 Compose 挂载均固定为 `/var/run/docker.sock`;不能只覆盖环境变量 | | `docker-gateway` | `BROWSER_NETWORK` | `creatorhub_browser` | | `docker-gateway` | `LOG_LEVEL` | 默认 `info` | 不要把凭据写入仓库或 Compose 文件。 ## 更新与回滚 更新前记录当前版本并备份数据库: ```bash set -Eeuo pipefail git rev-parse HEAD umask 077 export BACKUP_FILE="$(pwd)/creatorhub-$(date +%Y%m%d-%H%M%S).dump" docker compose exec -T postgres \ pg_dump -U creatorhub -d creatorhub --format=custom \ > "$BACKUP_FILE" test -s "$BACKUP_FILE" docker compose exec -T postgres pg_restore --list \ < "$BACKUP_FILE" >/dev/null ``` 拉取已审核版本后,重新执行部署和验证: ```bash set -Eeuo pipefail git pull --ff-only export DOCKER_GID="$(stat -c '%g' /var/run/docker.sock)" export CREATORHUB_PORT=8080 docker pull git.ipao.vip/rogee/fingerprint-chromium@sha256:b9f23b8e3ac640174db0dfa49e9095fe7eb06f5db55a4e7550d979b35ff3a1b7 docker compose config --quiet docker compose up --detach --build ``` 数据库迁移只支持安全前进,不提供自动破坏性回滚。需要同时恢复旧代码和更新前数据库时,修改下面两个变量后**整块执行一次**;不要逐行或拆块执行。预检、恢复演练、动态容器回收、停服、主库恢复、提交切换和启动都位于同一个 fail-fast subshell 中。 ```bash ( set -Eeuo pipefail BACKUP_FILE=/absolute/path/to/creatorhub-YYYYmmdd-HHMMSS.dump RESTORE_REV=PREVIOUS_REVIEWED_COMMIT_SHA : "${BACKUP_FILE:?set BACKUP_FILE to the absolute archive path}" : "${RESTORE_REV:?set RESTORE_REV to the previous reviewed commit SHA}" test -r "$BACKUP_FILE" test -s "$BACKUP_FILE" git cat-file -e "${RESTORE_REV}^{commit}" docker compose exec -T postgres pg_restore --list \ < "$BACKUP_FILE" >/dev/null docker compose exec -T postgres \ dropdb --if-exists --force -U creatorhub creatorhub_restore_check docker compose exec -T postgres \ createdb -U creatorhub creatorhub_restore_check docker compose exec -T postgres \ pg_restore -U creatorhub -d creatorhub_restore_check \ --exit-on-error --no-owner --no-privileges \ < "$BACKUP_FILE" docker compose exec -T postgres \ psql -U creatorhub -d creatorhub_restore_check -v ON_ERROR_STOP=1 -tAc \ 'SELECT 1 FROM schema_migration WHERE version = 1;' \ | grep -qx 1 docker compose exec -T postgres \ dropdb --force -U creatorhub creatorhub_restore_check docker ps --all --quiet \ --filter 'name=^creatorhub-browser-' \ --filter 'label=io.creatorhub.managed=true' \ --filter 'label=io.creatorhub.runtime-id' \ | xargs --no-run-if-empty docker rm --force docker compose stop creator-hub docker-gateway umask 077 PRE_ROLLBACK_BACKUP="$(pwd)/creatorhub-pre-rollback-$(date +%Y%m%d-%H%M%S).dump" docker compose exec -T postgres \ pg_dump -U creatorhub -d creatorhub --format=custom \ > "$PRE_ROLLBACK_BACKUP" test -s "$PRE_ROLLBACK_BACKUP" docker compose exec -T postgres pg_restore --list \ < "$PRE_ROLLBACK_BACKUP" >/dev/null test -r "$BACKUP_FILE" test -s "$BACKUP_FILE" git cat-file -e "${RESTORE_REV}^{commit}" docker compose exec -T postgres pg_restore --list \ < "$BACKUP_FILE" >/dev/null docker compose exec -T postgres \ dropdb --if-exists --force -U creatorhub creatorhub docker compose exec -T postgres createdb -U creatorhub creatorhub docker compose exec -T postgres \ pg_restore -U creatorhub -d creatorhub \ --exit-on-error --no-owner --no-privileges \ < "$BACKUP_FILE" docker compose exec -T postgres \ psql -U creatorhub -d creatorhub -v ON_ERROR_STOP=1 -tAc \ 'SELECT 1 FROM schema_migration WHERE version = 1;' \ | grep -qx 1 git switch --detach "$RESTORE_REV" if ! docker compose up --detach --build; then docker compose stop creator-hub docker-gateway || true exit 1 fi ) ``` 任何命令失败时 subshell 立即退出;若失败发生在主库 `dropdb` 之后,应用保持停止。`docker compose up` 自身失败时也会显式停回应用服务。成功后重新执行“部署验证”。不要直接删除数据卷或手工改写迁移记录。 ## 停止与数据保留 `docker compose stop/down` 不管理网关动态创建的浏览器容器;直接执行会留下运行中的浏览器和活动会话。先严格按固定容器名前缀及两个管理标签筛选并回收,命令不带 `--volumes`,因此 Profile 卷仍会保留: ```bash docker ps --all --quiet \ --filter 'name=^creatorhub-browser-' \ --filter 'label=io.creatorhub.managed=true' \ --filter 'label=io.creatorhub.runtime-id' \ | xargs --no-run-if-empty docker rm --force test -z "$(docker ps --all --quiet \ --filter 'name=^creatorhub-browser-' \ --filter 'label=io.creatorhub.managed=true' \ --filter 'label=io.creatorhub.runtime-id')" docker compose stop ``` 恢复服务使用 `docker compose up --detach`。需要删除服务容器和网络但保留数据时使用: ```bash docker compose down ``` 不要执行 `docker compose down --volumes`:它会删除 PostgreSQL 数据卷。浏览器 Profile 卷不属于 Compose 声明卷,删除浏览器容器或执行 `docker compose down` 时仍会保留;可用以下命令核对: ```bash docker volume ls --filter name=creatorhub-profile- ``` `docker.sock` 即使以只读文件方式挂载,也仍允许 Docker API 写操作,等价于宿主机 root 权限。完整安全边界、API 契约和失败语义见[《浏览器容器控制面》](architecture/container-control.md)。