文档目录
安装部署

Docker 部署

使用容器运行 ]project-open[,包括持久化、反向代理、备份与升级。

最后更新:2026-10-22

部署拓扑

生产环境推荐的最小拓扑:

Internet
  │  HTTPS
  ▼
Nginx(TLS、静态资源、反向代理)
  │
  ├── app(]project-open[)
  └── db(PostgreSQL)
        │
        └── 备份任务(每日 pg_dump + 附件同步)

应用与数据库分容器运行,数据通过命名卷持久化。Nginx 负责证书与超时设置,应用容器不对公网暴露端口。

Compose 示例

services:
  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_DB: projectopen
      POSTGRES_USER: projectopen
      POSTGRES_PASSWORD: ${DB_PASSWORD:?请设置 DB_PASSWORD}
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U projectopen -d projectopen"]
      interval: 10s
      timeout: 5s
      retries: 12

  app:
    image: ${PROJECT_OPEN_IMAGE:?请设置 PROJECT_OPEN_IMAGE}
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    environment:
      DB_HOST: db
      DB_NAME: projectopen
      DB_USER: projectopen
      DB_PASSWORD: ${DB_PASSWORD}
      SITE_URL: https://pm.example.com
    volumes:
      - app-data:/var/lib/project-open
    expose:
      - "8000"

volumes:
  db-data:
  app-data:

配套的 .env 只保存在服务器上,并设置 chmod 600:

DB_PASSWORD=<强口令>
PROJECT_OPEN_IMAGE=<你的镜像地址与版本标签>

不要在镜像标签中使用 latest 进行生产部署。固定版本标签才能在回滚时复现环境。

反向代理

server {
    listen 443 ssl http2;
    server_name pm.example.com;

    ssl_certificate     /etc/letsencrypt/live/pm.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/pm.example.com/privkey.pem;

    client_max_body_size 50m;
    proxy_read_timeout   300s;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

如果应用需要识别真实客户端 IP(用于审计或限流),确认应用读取的是 X-Forwarded-For,而不是反向代理的地址。

数据持久化

需要持久化的内容有两类:

  1. 数据库卷:db-data,包含全部业务数据;
  2. 应用数据卷:app-data,通常包含附件、上传文件与运行期缓存。

缓存目录可以不备份,但附件必须与数据库一起备份,否则恢复后会出现“记录存在、文件丢失”。

备份

每日执行数据库逻辑备份,并同步附件目录:

#!/usr/bin/env bash
set -euo pipefail

STAMP=$(date +%Y%m%d-%H%M)
BACKUP_DIR=/srv/backup/project-open

mkdir -p "$BACKUP_DIR"

docker compose exec -T db pg_dump -U projectopen -Fc projectopen \
  > "$BACKUP_DIR/db-$STAMP.dump"

docker run --rm \
  -v project-open_app-data:/data:ro \
  -v "$BACKUP_DIR":/backup \
  alpine tar czf "/backup/app-data-$STAMP.tar.gz" -C /data .

# 保留最近 14 天
find "$BACKUP_DIR" -type f -mtime +14 -delete

至少每季度做一次恢复演练:

docker compose stop app
docker compose exec -T db dropdb -U projectopen projectopen
docker compose exec -T db createdb -U projectopen projectopen
docker compose exec -T db pg_restore -U projectopen -d projectopen < db-20261001-0200.dump
docker compose start app

升级流程

  1. 阅读目标版本的发布说明,确认是否有数据库迁移;
  2. 完成一次完整备份;
  3. 在预发环境使用同一份数据演练升级;
  4. 修改 PROJECT_OPEN_IMAGE 版本标签,执行 docker compose up -d app;
  5. 观察日志与核心页面,确认迁移完成;
  6. 若失败,回退镜像标签并恢复数据。

日志与监控

  • 应用日志输出到标准输出,由 Docker 日志驱动收集;
  • 建议为日志设置轮转:max-size=20m、max-file=5;
  • 监控至少覆盖:容器存活、HTTP 5xx 比例、响应时间、数据库连接数、磁盘使用率。

安全检查

  • 数据库端口不映射到公网;
  • 管理后台限制来源 IP 或接入 VPN;
  • 定期轮换数据库口令与管理员口令;
  • 关闭不需要的演示包与示例数据;
  • 审计日志保留周期符合企业合规要求。