02 安装部署与系统维护

面向运维人员: 环境要求、部署步骤、日常维护与故障处理。


🎯 选择部署模式

软件支持三种部署模式,同一套代码,不改程序,只改配置。用户根据自身需求选择即可。

模式 应用服务器 数据库 文件存储 用户访问 适合场景
🏢 本地部署 公司内网服务器 本地 MySQL 本地磁盘 公司内网访问 数据不出企业、
网络封闭的工地
☁️ 云端部署 云服务器 云数据库 RDS 云 OSS 存储 互联网任意访问 省运维、
多项目多地使用
🔗 混合部署
(计算上云·数据留本地) 云服务器 公司内网 MySQL
(通过 VPN 隧道) 公司内网文件服务器
(通过 VPN 隧道) 外网+内网皆可 要云端计算能力,
但数据必须留在企业内部

💡 常见误解: 云部署 ≠ 数据上云。混合模式下,软件跑在云服务器上,但你的数据库和文件依然保存在公司内部服务器里。云服务器只是一个”远程操作台”,操作完的数据回传到你自己的数据库。

如何选择

┌ 数据必须留在企业内部?
├── 是 → 公司有运维能力?
│       ├── 是 → 🏢 本地部署(最简单)
│       └── 否 → 🔗 混合部署(云服务器算,数据留本地)
└── 否 → 公司有固定运维人员?
        ├── 有 → 🏢 本地部署
        └── 无 → ☁️ 云端部署(云服务商帮管数据库和备份)

环境要求

组件 版本要求 说明
Python ≥ 3.14 后端运行环境
Node.js ≥ 20 前端编译
MySQL 8.0 生产数据库(可选 PostgreSQL)
Redis 7.x 缓存 + 消息队列
Docker ≥ 24 容器化部署(可选)
Nginx ≥ 1.24 反向代理

开发环境可使用 SQLite,生产环境推荐 MySQL 8.0 或 PostgreSQL。


Docker 部署(推荐)

前置准备

# 克隆项目
git clone <项目仓库地址> /opt/sa-power
cd /opt/sa-power

# 创建环境变量文件
cp .env.example .env
# 编辑 .env,填写 DJANGO_SECRET_KEY、MYSQL_ROOT_PASSWORD 等必要变量

启动服务

docker-compose.yml 位于项目根目录(src/docker-compose.yml),提供三种 profile:

# 开发模式(仅后端 + DB + Redis)
docker compose --profile dev up -d

# 完整模式(含前端 + Celery Worker + Beat)
docker compose --profile full up -d

# 生产模式(含 Nginx 反向代理)
docker compose --profile prod up -d

验证部署

# 检查容器状态
docker compose ps

# 查看后端日志
docker compose logs -f web

# 测试 API 是否正常
curl http://localhost:8000/api/health/

🔗 混合部署(计算上云·数据留本地)

应用服务器部署到云上,但数据库和上传文件留在公司内网。

部署拓扑

┌─ 云服务器 ─────────────────────┐
│  Django APP(Nginx + Gunicorn) │
│  前端 Vue (编译后静态文件)       │
│  Redis (缓存,可放云上)         │
└─────────────┬──────────────────┘
              │ VPN 加密隧道
┌─────────────▼──────────────────┐
│ 公司内网服务器                    │
│  MySQL 数据库                     │
│  上传文件存储(NFS / 本地磁盘)    │
│  (可选)敏感 Redis               │
└────────────────────────────────┘

操作步骤

  1. 内网服务器 — 准备好 MySQL 服务器和文件存储目录

  2. 建 VPN 隧道 — WireGuard(最简单)或 OpenVPN,打通云服务器和内网

    # 内网服务器上安装 WireGuard,分配一个虚拟 IP(如 10.0.0.2)
    # 云服务器上安装 WireGuard,也分配一个虚拟 IP(如 10.0.0.1)
    # 两边配好密钥对,互相能 ping 通即可
  3. 云服务器 .env 配置 — 数据库地址指向内网 IP

    USE_MYSQL=True
    MYSQL_HOST=10.0.0.2    ← 内网数据库的 WireGuard IP
    MYSQL_PASSWORD=xxx
    FILE_STORAGE=local
    MEDIA_ROOT=/mnt/nfs/uploads  ← 或挂载内网的 NFS 共享目录
  4. 正常启动云服务器上的 Docker 或手动部署

⚠️ 注意


📋 三种模式一键切换

三种部署模式的区别就是 .env 配置文件里的几行参数不同,其他完全一样。

配置项 🏢 本地部署 ☁️ 云端部署 🔗 混合部署
应用服务器位置 公司内网 云服务器 云服务器
DJANGO_DEBUG False False False
USE_MYSQL True True True
MYSQL_HOST 127.0.0.1 云数据库地址 内网 IP(VPN)
MYSQL_DATABASE sa_power sa_power sa_power
文件存储 MEDIA_ROOT=本地路径 OSS / S3 配置 NFS 挂载路径
备份方式 本地 crontab 云数据库自动备份 内网 crontab

切换模式只需换 .env 文件 + 迁移数据,不涉及程序代码的任何修改。

从本地迁移到云端

如果之前用本地部署,现在想上云,数据迁移步骤:

# 1. 在本地服务器导出数据库
mysqldump -u root -p sa_power_db > export.sql

# 2. 把文件传到云服务器
scp export.sql user@云服务器:/tmp/

# 3. 导入云数据库
mysql -h 云数据库地址 -u admin -p sa_power_db < /tmp/export.sql

# 4. 上传文件从本地拷贝到云存储(OSS/S3)
# 5. 换 `.env` 配置,重启服务

手动部署

1. 后端(Django)

# 创建 Python 虚拟环境
python3 -m venv .venv
source .venv/bin/activate

# 安装依赖
pip install -r requirements.txt

# 配置环境变量
export DJANGO_SECRET_KEY="your-generated-secret-key"
export DJANGO_DEBUG=False
export DJANGO_ALLOWED_HOSTS=localhost,your-domain.com
export USE_MYSQL=True
export MYSQL_PASSWORD=your-db-password

# 数据库迁移
python manage.py migrate

# 收集静态文件
python manage.py collectstatic --noinput

# 启动后端服务(开发)
python manage.py runserver 0.0.0.0:8000

# 或使用 Gunicorn(生产)
gunicorn config.wsgi:application -w 4 -b 0.0.0.0:8000

2. 前端(Vue 3)

cd frontend

# 安装依赖
npm install

# 编译生产版本
npm run build

# 开发模式(热更新)
npx vite --port 3000

3. 移动端 H5

cd h5

# 安装依赖
npm install

# 编译
npm run build

# 开发模式
npx vite --port 3002

Nginx 配置

项目根目录提供 src/nginx.conf 配置文件。典型配置要点:

# API 反向代理
location /api/ {
    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;
}

# WebSocket 代理
location /ws/ {
    proxy_pass http://127.0.0.1:8000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

# 前端静态文件
location / {
    root /path/to/frontend/dist;
    try_files $uri $uri/ /index.html;
}

安全提示: 生产环境请配置 SSL 证书(Let’s Encrypt 免费证书),并开启 HSTS。


日常维护

数据库备份

本地部署 / 混合部署:

# MySQL 备份到内网存储
mysqldump -u root -p sa_power_db > /data/backup/backup_$(date +%Y%m%d).sql

# 建议设置 crontab 自动备份
0 2 * * * mysqldump -u root -p密码 sa_power_db > /data/backup/daily_$(date +\%Y\%m\%d).sql

云端部署: - 使用云数据库的自动备份功能(阿里云 RDS 每天自动备份,保留 7~30 天) - 也可每月一次手动拉回本地存档

mysqldump -h 云数据库地址 -u admin -p sa_power_db > local_backup_$(date +%Y%m%d).sql

数据库恢复

# MySQL 恢复
mysql -u root -p sa_power_db < backup_20260601.sql
python manage.py migrate

日志查看

# Django 应用日志
tail -f logs/app.log

# 审计日志
tail -f logs/audit.log

# Docker 日志
docker compose logs -f --tail=100 web

升级更新

# 拉取最新代码
git pull

# 更新后端依赖
source .venv/bin/activate
pip install -r requirements.txt

# 执行数据库迁移
python manage.py migrate

# 更新前端
cd frontend && npm install && npm run build

# 重启服务
# Docker 部署:
docker compose restart web

# 手动部署:
systemctl restart sa-power  # 或 supervisorctl restart

常见故障处理

端口占用

# 检查端口占用
lsof -i :8000

# 终止占用进程
kill -9 <PID>

# 或更换端口
python manage.py runserver 0.0.0.0:8001

数据库连接失败

# 检查数据库服务是否运行
systemctl status mysql

# 检查数据库凭证(.env 文件)
# 确认 DB_NAME / DB_USER / DB_PASSWORD 正确

# 测试连接
mysql -u sa_power_user -p -h 127.0.0.1 -e "SELECT 1"

权限错误

# 检查文件权限
ls -la db.sqlite3
chmod 644 db.sqlite3

# Django 密钥检查
# 确保 DJANGO_SECRET_KEY 环境变量已设置且有效

# 日志文件权限
chmod -R 755 logs/

WebSocket 连接失败

# 确认 daphne/Channels 已运行
# 生产环境需配置 Nginx WebSocket 代理(参见上方 Nginx 配置)
# 检查 Redis 是否可访问
redis-cli ping  # 应返回 PONG