diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3d8d363d5..2829f958e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -315,6 +315,7 @@ jobs: shell: bash env: VERSION: ${{ needs.release-info.outputs.version }} + DOCKER_VERSION: ${{ needs.release-info.outputs.docker_version }} run: | set -euo pipefail ruby <<'RUBY' > release-platforms.json @@ -349,7 +350,18 @@ jobs: shutil.rmtree(release_dir, ignore_errors=True) release_dir.mkdir(parents=True) - archives = [] + config_template = pathlib.Path("deploy/config.example.yaml") + shutil.copy2(config_template, release_dir / config_template.name) + compose = pathlib.Path("deploy/compose.yaml").read_text() + image = f"{os.environ['REGISTRY']}/{os.environ['IMAGE_NAME']}" + default_image = "${CPR_IMAGE:-" + image + ":latest}" + if compose.count(default_image) != 1: + raise SystemExit("Expected exactly one default application image in deploy/compose.yaml") + # 发布附件固定镜像版本,防止后续 pull 与随包配置模板脱节。 + versioned_image = "${CPR_IMAGE:-" + f"{image}:{os.environ['DOCKER_VERSION']}" + "}" + compose = compose.replace(default_image, versioned_image) + (release_dir / "compose.yaml").write_text(compose) + assets = [release_dir / config_template.name, release_dir / "compose.yaml"] for platform in platforms: platform_name = f"{platform['os']}-{platform['arch']}" @@ -367,6 +379,9 @@ jobs: shutil.copy2(binary_src, binary_dest) binary_dest.chmod(0o755) shutil.copytree(frontend_dir, web_dist, dirs_exist_ok=True) + deploy_dir = package_root / "deploy" + deploy_dir.mkdir() + shutil.copy2(config_template, deploy_dir / config_template.name) archive_name = f"{APP_NAME}_{version}_{platform['os']}_{platform['arch']}.{platform['archive']}" archive_path = release_dir / archive_name @@ -375,12 +390,12 @@ jobs: archive.add(package_root, arcname=APP_NAME) else: raise SystemExit(f"Unsupported archive format: {platform['archive']}") - archives.append(archive_path) + assets.append(archive_path) checksum_path = release_dir / "checksums.txt" with checksum_path.open("w", encoding="utf-8") as file: - for archive in archives: - file.write(f"{sha256(archive)} {archive.name}\n") + for asset in assets: + file.write(f"{sha256(asset)} {asset.name}\n") PY - name: Generate release asset provenance @@ -655,25 +670,27 @@ jobs: env: INSTALLATION_NOTES: | > [!WARNING] - > **Upgrading across major versions?** Online upgrades across major versions are not supported. Deploy the new major fresh with a new `.runtime/` data directory, then re-import or re-authorize provider accounts and client keys. See the [upgrade notes](https://github.com/${{ github.repository }}/blob/main/deploy/README.md#镜像升级与源码构建). + > **跨大版本升级:** 不支持跨大版本在线升级。请使用全新的 `.runtime/` 数据目录重新部署,再重新导入或重新授权服务商账号,并重新导入客户端密钥。详见[升级说明](https://github.com/${{ github.repository }}/blob/${{ needs.release-info.outputs.tag }}/deploy/README.md#镜像升级与源码构建)。 - ## 📥 Installation + ## 📥 安装 - **Docker:** + **Docker 部署:** ```bash - # GitHub Container Registry + # 从 GitHub 容器镜像仓库拉取 docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.release-info.outputs.docker_version }} ``` - **Manual download:** - Download the appropriate archive for your platform from the assets below. + 请从本版本附件下载 `compose.yaml` 和 `config.example.yaml`。Compose 默认固定到本版本镜像;升级前请对比模板与已有配置。 - Release archives are covered by GitHub artifact attestations. Docker images are published with SBOM/provenance attestations and keyless cosign signatures. + **手动下载:** + 请从下方附件中下载适合当前平台的归档包。 - ## 📚 Documentation + 发布归档提供 GitHub 构建产物证明。Docker 镜像附带软件物料清单(SBOM)、构建来源证明和 cosign 无密钥签名。 - - [GitHub Repository](https://github.com/${{ github.repository }}) - - [Installation Guide](https://github.com/${{ github.repository }}/blob/main/deploy/README.md) + ## 📚 文档 + + - [GitHub 仓库](https://github.com/${{ github.repository }}) + - [部署指南](https://github.com/${{ github.repository }}/blob/${{ needs.release-info.outputs.tag }}/deploy/README.md) run: | python3 <<'PY' import os diff --git a/README.md b/README.md index fab5f702f..a371a4d29 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ ## 快速开始 -使用 Docker Compose 部署发布镜像 `ghcr.io/zyycn/codex-proxy-rs:latest`,同时启动 PostgreSQL 和 Redis。 +使用 Docker Compose 部署版本固定的发布镜像,同时启动 PostgreSQL 和 Redis。 以下命令适用于 Linux amd64/arm64,需要 Docker Engine、Docker Compose Plugin、curl 和 OpenSSL。已有部署请先看 [升级说明](deploy/README.md#镜像升级与源码构建),不要覆盖原配置。 @@ -30,9 +30,12 @@ ```bash mkdir -p codex-proxy-rs/deploy && cd codex-proxy-rs -curl -fsSL https://raw.githubusercontent.com/zyycn/codex-proxy-rs/main/deploy/compose.yaml \ +# 只解析一次最新正式版本,确保两个文件来自同一 Release。 +CPR_RELEASE_URL="$(curl -fsSL -o /dev/null -w '%{url_effective}' https://github.com/zyycn/codex-proxy-rs/releases/latest)" +CPR_RELEASE_TAG="${CPR_RELEASE_URL##*/}" +curl -fsSL "https://github.com/zyycn/codex-proxy-rs/releases/download/${CPR_RELEASE_TAG}/compose.yaml" \ -o deploy/compose.yaml -curl -fsSL https://raw.githubusercontent.com/zyycn/codex-proxy-rs/main/deploy/config.example.yaml \ +curl -fsSL "https://github.com/zyycn/codex-proxy-rs/releases/download/${CPR_RELEASE_TAG}/config.example.yaml" \ -o deploy/config.example.yaml install -d -m 0750 .runtime/postgres .runtime/redis @@ -40,6 +43,9 @@ sudo install -d -m 0770 -o "$(id -u)" -g 10001 .runtime/data .runtime/logs sudo install -m 0640 -o "$(id -u)" -g 10001 deploy/config.example.yaml deploy/config.yaml ``` +也可将 `CPR_RELEASE_TAG` 设置为指定的发布标签。Release 附带的 `compose.yaml` 默认使用该版本镜像, +配置模板和部署文件均包含在 `checksums.txt` 中;不要混用 `main` 分支模板与已发布镜像。 + 分别生成数据库和 Redis 密码: ```bash diff --git a/deploy/README.md b/deploy/README.md index a059efeb5..9b330a14c 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -332,7 +332,13 @@ OpenAI 主动额度重置卡及其消费结果由上游持有,不写入 Postgr > 以下命令只适用于同一大版本内的升级,不支持跨大版本在线升级。跨大版本请使用全新的 > `.runtime/` 数据目录重新部署,并重新导入或重新授权 Provider 账号与客户端 Key。 -Docker 安装从安装目录拉取发布镜像并重建应用容器: +每个 Release 独立提供 `config.example.yaml`、默认镜像固定到该版本的 `compose.yaml` 和校验和; +各平台归档也包含 `deploy/config.example.yaml`。配置模板来自构建该版本的同一提交。 +使用二进制归档手动部署时,将模板中的 `api.asset_directory` 改为 `../web/dist`,指向归档内的静态资源。 +升级时先阅读目标版本说明,下载同一 Release 的部署附件,对比模板并合并必要配置,保留已有凭据 +和 Compose 自定义项。不要用模板覆盖 `config.yaml`,也不要从 `main` 下载模板搭配旧镜像。 + +更新部署文件后,从安装目录拉取目标版本镜像并重建应用容器: ```bash docker compose -f deploy/compose.yaml pull codex-proxy-rs