# 生产部署 (Docker) 用 `docker-compose.prod.yml` 部署,与本地 `docker-compose.yml` 的区别: - 仅 `api` 映射宿主端口,且绑定 `127.0.0.1:8120`(由外层 nginx 反代 + HTTPS);`postgres`/`redis`/`minio` 不对外暴露端口,仅容器内网互通。 - 所有服务 `restart: unless-stopped`。 - 凭据从 `.env` 注入(见 `.env.example`),不写入仓库。 - `api` 使用 `api/Dockerfile.prod`:运行镜像用 `scratch`(从构建镜像拷贝 ca-certs),适用于 `gcr.io/distroless` 不可达的环境;Go 模块走 `goproxy.cn`。 - `admin`(运营后台):带登录的写入服务 + 内嵌前端,绑定 `127.0.0.1:8121`,由 nginx 反代到公开站点的 `/ping` 路径。镜像 `api/Dockerfile.admin`(node 构建前端 → 内嵌进 Go 二进制 → scratch 运行)。仅 `admin` 可写库(人工编辑以 `source=manual` 记录字段级溯源 + `audit_log` 留痕),公开 `api` 仍只读。 ## 步骤 ```bash cp .env.example .env # 填入真实随机密码 docker compose -f docker-compose.prod.yml up -d --build # 迁移(migrate 容器接入同一网络,DSN 指向 postgres 服务) set -a; . ./.env; set +a DBURL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=disable" docker run --rm --network goods_default -v "$PWD/migrations:/migrations" \ migrate/migrate -path=/migrations -database "$DBURL" up curl -s http://127.0.0.1:8120/healthz # {"status":"ok"} ``` nginx 反代(子域 + HTTPS):80 端口 301 跳转到 443,443 `proxy_pass http://127.0.0.1:8120`,证书用 acme.sh 签发并配 `--reloadcmd "nginx -s reload"` 自动续期。 运营后台 `/ping`(同域复用证书):在 443 server 块内加一段 ```nginx location /ping { proxy_pass http://127.0.0.1:8121; } ``` 后台凭据见 `.env` 的 `GOODS_ADMIN_USER` / `GOODS_ADMIN_PASSWORD` / `GOODS_ADMIN_JWT_SECRET`。新增迁移 `0005_admin`(`audit_log` 表 + `manual` 来源)随 `migrate ... up` 自动应用。