fix: standardize Docker timezone

Set the runtime image and PostgreSQL service to Asia/Shanghai while preserving UTC timestamptz storage semantics.

Verify the application and PostgreSQL timezone contracts in the container workflow and document the display behavior.

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
zyycn
2026-07-12 21:38:14 +08:00
co-authored by Codex
parent d94bca33dd
commit a8f5c5a54e
5 changed files with 23 additions and 1 deletions
+4
View File
@@ -122,6 +122,8 @@ jobs:
compose=(docker compose --project-name "$COMPOSE_PROJECT_NAME" \
-f deploy/docker-compose.yml -f deploy/docker-compose.smoke.yml)
"${compose[@]}" up -d --no-build --wait postgres redis
test "$("${compose[@]}" exec -T -e PGPASSWORD="$CPR_POSTGRES_PASSWORD" postgres \
psql -At -U codex_proxy -d codex_proxy -c "SHOW TimeZone;" | tr -d '\r')" = Asia/Shanghai
"${compose[@]}" exec -T -e PGPASSWORD="$CPR_POSTGRES_PASSWORD" postgres \
psql -v ON_ERROR_STOP=1 -U codex_proxy -d codex_proxy -c \
"CREATE TABLE cpr_ci_persistence_probe (value text PRIMARY KEY); INSERT INTO cpr_ci_persistence_probe VALUES ('persisted');"
@@ -151,6 +153,8 @@ jobs:
test "$status" = 204
test "$("${compose[@]}" exec -T codex-proxy-rs id -u | tr -d '\r')" = 10001
test "$("${compose[@]}" exec -T codex-proxy-rs id -g | tr -d '\r')" = 10001
test "$("${compose[@]}" exec -T codex-proxy-rs date +%z | tr -d '\r')" = +0800
test "$("${compose[@]}" exec -T codex-proxy-rs cat /etc/timezone | tr -d '\r')" = Asia/Shanghai
"${compose[@]}" exec -T codex-proxy-rs sh -c \
'touch /app/data/.ci-write /app/logs/.ci-write && rm /app/data/.ci-write /app/logs/.ci-write'
+5 -1
View File
@@ -51,8 +51,12 @@ COPY --from=release-asset-builder /out /
FROM debian:bookworm-slim@sha256:60eac759739651111db372c07be67863818726f754804b8707c90979bda511df AS runtime-base
ENV TZ=Asia/Shanghai
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates curl \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates curl tzdata \
&& ln -snf "/usr/share/zoneinfo/${TZ}" /etc/localtime \
&& printf '%s\n' "${TZ}" > /etc/timezone \
&& groupadd --system --gid 10001 cpr \
&& useradd --system --uid 10001 --gid cpr --home-dir /app --shell /usr/sbin/nologin cpr \
&& install -d -o cpr -g cpr /app/bin /app/data /app/logs /app/web \
+3
View File
@@ -26,6 +26,9 @@ chmod 0600 deploy/.env
应用日志同时写入 `docker logs` 与 `.runtime/logs`。Compose 对应用、PostgreSQL、Redis
统一启用 `json-file` 的 `10m × 5` 轮转;应用文件日志还受配置中的自然日、单文件大小和文件总数限制。
Runtime 镜像和 PostgreSQL 的显示、日志时区固定为 `Asia/Shanghai`。PostgreSQL 时间列仍使用
`timestamptz` 保存绝对时间点,修改时区只影响查询与日志的显示,不需要迁移或改写已有数据。
`deploy/.env` 是 Docker 部署的密钥配置文件,已被 Git 忽略且必须保持 mode `0600`。其中
`CPR_ADMIN_DEFAULT_PASSWORD`、`CPR_POSTGRES_PASSWORD`、`CPR_REDIS_PASSWORD` 三项均为必填,
留空时 Compose 会在启动前失败。管理员密码必须至少 12 位且不能是常见弱口令。
+9
View File
@@ -10,7 +10,16 @@ services:
postgres:
image: postgres:18-bookworm@sha256:d9c83446333daec3f0588cc709adb80c26090b7f9f0f7ec8d43c243385d79818
restart: unless-stopped
command:
[
"postgres",
"-c",
"timezone=Asia/Shanghai",
"-c",
"log_timezone=Asia/Shanghai",
]
environment:
TZ: Asia/Shanghai
POSTGRES_DB: codex_proxy
POSTGRES_USER: codex_proxy
POSTGRES_PASSWORD: ${CPR_POSTGRES_PASSWORD:?CPR_POSTGRES_PASSWORD must be set in deploy/.env}
+2
View File
@@ -445,6 +445,8 @@ Responses 协议没有按事件序号续传未完成 response 的请求字段。
PostgreSQL 是权威持久化存储。
时间列统一使用 `timestamptz`,应用以 UTC 时间点读写。Compose 将 PostgreSQL 的会话显示时区和日志时区设为 `Asia/Shanghai`,因此直接查询时显示 `+08:00`;这不会改写已有数据,也不会改变数据库内部保存的绝对时间。API 输出、中国自然日统计和日志轮转仍由 `infra::time` 显式定义,不依赖宿主机时区。
| 数据 | 表 |
| --- | --- |
| 管理员 | `admin_users` |