mirror of
https://github.com/zyycn/codex-proxy-rs.git
synced 2026-11-06 08:06:19 +00:00
feat: harden deployment and CI pipeline
Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
# Docker deployment secrets. Copy this file to deploy/.env and set every value.
|
||||
CPR_ADMIN_DEFAULT_PASSWORD=''
|
||||
CPR_POSTGRES_PASSWORD=''
|
||||
CPR_REDIS_PASSWORD=''
|
||||
+8
-5
@@ -1,6 +1,6 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
# syntax=docker/dockerfile:1.7@sha256:a57df69d0ea827fb7266491f2813635de6f17269be881f696fbfdf2d83dda33e
|
||||
|
||||
FROM node:24-bookworm-slim AS frontend-builder
|
||||
FROM node:24-bookworm-slim@sha256:cb4e8f7c443347358b7875e717c29e27bf9befc8f5a26cf18af3c3dec80e58c5 AS frontend-builder
|
||||
|
||||
WORKDIR /app/frontend
|
||||
COPY frontend/package.json frontend/pnpm-lock.yaml frontend/pnpm-workspace.yaml ./
|
||||
@@ -8,7 +8,7 @@ RUN corepack enable && pnpm install --frozen-lockfile
|
||||
COPY frontend ./
|
||||
RUN pnpm build
|
||||
|
||||
FROM rust:1.95-bookworm AS backend-builder
|
||||
FROM rust:1.95-bookworm@sha256:6258907abe69656e41cd992e0b705cdcfabcbbe3db374f92ed2d47121282d4a1 AS backend-builder
|
||||
|
||||
WORKDIR /app/backend
|
||||
ARG TARGETARCH
|
||||
@@ -38,7 +38,10 @@ ARG TARGETARCH
|
||||
|
||||
WORKDIR /out
|
||||
COPY --from=frontend-builder /app/frontend/dist /tmp/release/codex-proxy-rs/web/dist
|
||||
RUN cp /tmp/codex-proxy-rs /tmp/release/codex-proxy-rs/ \
|
||||
RUN test -n "${CPR_VERSION}" \
|
||||
&& test -n "${TARGETOS}" \
|
||||
&& test -n "${TARGETARCH}" \
|
||||
&& cp /tmp/codex-proxy-rs /tmp/release/codex-proxy-rs/ \
|
||||
&& tar -czf "/out/codex-proxy-rs_${CPR_VERSION}_${TARGETOS}_${TARGETARCH}.tar.gz" \
|
||||
-C /tmp/release codex-proxy-rs
|
||||
|
||||
@@ -46,7 +49,7 @@ FROM scratch AS release-asset
|
||||
|
||||
COPY --from=release-asset-builder /out /
|
||||
|
||||
FROM debian:bookworm-slim AS runtime-base
|
||||
FROM debian:bookworm-slim@sha256:60eac759739651111db372c07be67863818726f754804b8707c90979bda511df AS runtime-base
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends ca-certificates curl \
|
||||
|
||||
+20
-10
@@ -9,6 +9,12 @@
|
||||
```bash
|
||||
mkdir -p .runtime/data .runtime/logs
|
||||
cp deploy/config.example.yaml .runtime/config.yaml
|
||||
sudo chown -R "$(id -u):10001" .runtime/data .runtime/logs
|
||||
chmod 0770 .runtime/data .runtime/logs
|
||||
sudo chown "$(id -u):10001" .runtime/config.yaml
|
||||
chmod 0640 .runtime/config.yaml
|
||||
cp deploy/.env.example deploy/.env
|
||||
chmod 0600 deploy/.env
|
||||
```
|
||||
|
||||
`deploy/config.example.yaml` 是 Docker 部署模板。Compose 默认使用仓库根目录的 `.runtime/`:
|
||||
@@ -20,20 +26,24 @@ cp deploy/config.example.yaml .runtime/config.yaml
|
||||
应用日志同时写入 `docker logs` 与 `.runtime/logs`。Compose 对应用、PostgreSQL、Redis
|
||||
统一启用 `json-file` 的 `10m × 5` 轮转;应用文件日志还受配置中的自然日、单文件大小和文件总数限制。
|
||||
|
||||
复制后必须设置 `admin.default_password`。空值、长度不足 12 位或常见弱口令会被后端拒绝。
|
||||
`deploy/.env` 是 Docker 部署的密钥配置文件,已被 Git 忽略且必须保持 mode `0600`。其中
|
||||
`CPR_ADMIN_DEFAULT_PASSWORD`、`CPR_POSTGRES_PASSWORD`、`CPR_REDIS_PASSWORD` 三项均为必填,
|
||||
留空时 Compose 会在启动前失败。管理员密码必须至少 12 位且不能是常见弱口令。
|
||||
|
||||
Redis 默认密码为 `codex_proxy`,与 `deploy/config.example.yaml` 的连接串一致。生产部署通过
|
||||
`CPR_REDIS_PASSWORD` 覆盖后,必须同步更新 `.runtime/config.yaml` 中 URL 的密码(特殊字符需做 URL 编码)。
|
||||
本地 Rust 集成测试若复用该 Compose Redis,设置
|
||||
`CPR_TEST_REDIS_URL=redis://:codex_proxy@127.0.0.1:6379/`。
|
||||
Compose 会把 PostgreSQL、Redis 密码的同一个值同时传给服务端和应用;应用使用 URL API 覆盖连接串
|
||||
密码,并用管理员密码覆盖 `admin.default_password`。因此无需修改 `.runtime/config.yaml` 中的密码,
|
||||
特殊字符也无需手工编码。本地 Rust 集成测试若复用该 Compose 服务,应使用与 `deploy/.env` 一致的
|
||||
测试连接串。
|
||||
编辑密码时保留 `deploy/.env` 中的单引号,使 `#`、`$` 等 Compose 语法字符按字面值传递。
|
||||
|
||||
如果前面还有 Nginx、Caddy、Cloudflare Tunnel 等反向代理,确保反代正常传递 `CF-Connecting-IP`、`X-Real-IP` 或 `X-Forwarded-For`。后端会按这组头自动解析真实客户端 IP;没有这些头时回落到直连 peer IP。
|
||||
|
||||
构建并启动:
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/docker-compose.yml build
|
||||
docker compose -f deploy/docker-compose.yml up -d
|
||||
# 先编辑 deploy/.env,设置全部三项密码。
|
||||
docker compose --env-file deploy/.env -f deploy/docker-compose.yml build
|
||||
docker compose --env-file deploy/.env -f deploy/docker-compose.yml up -d
|
||||
```
|
||||
|
||||
可以通过环境变量覆盖宿主机路径。容器内始终通过 `CPR_CONFIG_FILE=/app/config.yaml` 读取挂载后的配置:
|
||||
@@ -42,7 +52,7 @@ docker compose -f deploy/docker-compose.yml up -d
|
||||
CPR_CONFIG_FILE=/path/to/config.yaml \
|
||||
CPR_DATA_DIR=/path/to/data \
|
||||
CPR_LOG_DIR=/path/to/logs \
|
||||
docker compose -f deploy/docker-compose.yml up -d
|
||||
docker compose --env-file deploy/.env -f deploy/docker-compose.yml up -d
|
||||
```
|
||||
|
||||
## 构建
|
||||
@@ -56,7 +66,7 @@ docker build -f deploy/Dockerfile -t codex-proxy-rs:latest .
|
||||
也可以用 Compose 构建:
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/docker-compose.yml build
|
||||
docker compose --env-file deploy/.env -f deploy/docker-compose.yml build
|
||||
```
|
||||
|
||||
需要写入版本元数据时:
|
||||
@@ -65,5 +75,5 @@ docker compose -f deploy/docker-compose.yml build
|
||||
CPR_VERSION="$(ruby -ryaml -e 'puts YAML.load_file("release/version.yaml").fetch("version").delete_prefix("v")')" \
|
||||
CPR_GIT_SHA="$(git rev-parse HEAD)" \
|
||||
CPR_BUILD_TIME="$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
|
||||
docker compose -f deploy/docker-compose.yml build
|
||||
docker compose --env-file deploy/.env -f deploy/docker-compose.yml build
|
||||
```
|
||||
|
||||
@@ -84,7 +84,7 @@ fingerprint:
|
||||
admin:
|
||||
# 管理端登录会话有效期,单位分钟。
|
||||
session_ttl_minutes: 1440
|
||||
# 首次启动创建的默认管理员账号。default_password 必须改成至少 12 位的非默认密码。
|
||||
# 首次启动创建的默认管理员账号。Docker 部署通过 CPR_ADMIN_DEFAULT_PASSWORD 注入密码。
|
||||
default_username: admin@cpr.local
|
||||
default_password: ''
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
services:
|
||||
postgres:
|
||||
ports: !reset []
|
||||
|
||||
redis:
|
||||
ports: !reset []
|
||||
|
||||
codex-proxy-rs:
|
||||
container_name: ${COMPOSE_PROJECT_NAME}-app
|
||||
ports: !override
|
||||
- "127.0.0.1:${CPR_SMOKE_PORT:-18080}:8080"
|
||||
@@ -8,12 +8,12 @@ x-json-logging: &json-logging
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:18-alpine
|
||||
image: postgres:18-alpine@sha256:9a8afca54e7861fd90fab5fdf4c42477a6b1cb7d293595148e674e0a3181de15
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: codex_proxy
|
||||
POSTGRES_USER: codex_proxy
|
||||
POSTGRES_PASSWORD: ${CPR_POSTGRES_PASSWORD:-codex_proxy}
|
||||
POSTGRES_PASSWORD: ${CPR_POSTGRES_PASSWORD:?CPR_POSTGRES_PASSWORD must be set in deploy/.env}
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql
|
||||
ports:
|
||||
@@ -28,7 +28,7 @@ services:
|
||||
logging: *json-logging
|
||||
|
||||
redis:
|
||||
image: redis:8-alpine
|
||||
image: redis:8-alpine@sha256:9d317178eceac8454a2284a9e6df2466b93c745529947f0cd42a0fa9609d7005
|
||||
restart: unless-stopped
|
||||
command:
|
||||
[
|
||||
@@ -36,7 +36,7 @@ services:
|
||||
"--appendonly",
|
||||
"yes",
|
||||
"--requirepass",
|
||||
"${CPR_REDIS_PASSWORD:-codex_proxy}",
|
||||
"${CPR_REDIS_PASSWORD:?CPR_REDIS_PASSWORD must be set in deploy/.env}",
|
||||
]
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
@@ -49,7 +49,7 @@ services:
|
||||
"redis-cli",
|
||||
"--no-auth-warning",
|
||||
"-a",
|
||||
"${CPR_REDIS_PASSWORD:-codex_proxy}",
|
||||
"${CPR_REDIS_PASSWORD:?CPR_REDIS_PASSWORD must be set in deploy/.env}",
|
||||
"ping",
|
||||
]
|
||||
interval: 5s
|
||||
@@ -105,6 +105,9 @@ services:
|
||||
HOME: /app
|
||||
XDG_DATA_HOME: /app/data
|
||||
CPR_CONFIG_FILE: /app/config.yaml
|
||||
CPR_ADMIN_DEFAULT_PASSWORD: ${CPR_ADMIN_DEFAULT_PASSWORD:?CPR_ADMIN_DEFAULT_PASSWORD must be set in deploy/.env}
|
||||
CPR_POSTGRES_PASSWORD: ${CPR_POSTGRES_PASSWORD:?CPR_POSTGRES_PASSWORD must be set in deploy/.env}
|
||||
CPR_REDIS_PASSWORD: ${CPR_REDIS_PASSWORD:?CPR_REDIS_PASSWORD must be set in deploy/.env}
|
||||
CPR_DEPLOYMENT_MODE: docker
|
||||
CPR_UPDATE_REPOSITORY: zyycn/codex-proxy-rs
|
||||
CPR_UPDATE_CHANNEL: stable
|
||||
|
||||
Reference in New Issue
Block a user