Files
skelet/docs/deployment/deployment-guide.md
T

4.4 KiB
Raw Blame History

部署指南

适用于 2 核 2G VPS(Ubuntu 22.04/24.04),Gunicorn + Nginx + SQLite。

前置条件

# 确保系统已安装
python3.12 --version        # Python 3.12+
git --version               # Git
nginx -v                    # Nginx
# 如缺少 Python 3.12:
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.12 python3.12-venv python3.12-dev

一、应用部署

# 1. 克隆仓库
git clone http://ilaer.eicp.net:8418/opc/skelet.git /var/www/skelet
cd /var/www/skelet

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

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

# 4. 配置环境变量
cp .env.example .env
# 编辑 .env 填写真实密钥
export $(cat .env | xargs)

# 5. 静态文件收集 & 数据库迁移 & 种子数据
python manage.py collectstatic --noinput
python manage.py migrate
python manage.py createsuperuser
python manage.py seed_data --clear

# 6. 测试应用可运行
python manage.py check

二、Gunicorn Systemd Service

# /etc/systemd/system/skelet.service
[Unit]
Description=Skelet Gunicorn daemon
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/skelet
EnvironmentFile=/var/www/skelet/.env
ExecStart=/var/www/skelet/.venv/bin/gunicorn \
    --workers 2 \
    --bind unix:/var/www/skelet/run/gunicorn.sock \
    --access-logfile /var/log/skelet/access.log \
    --error-logfile /var/log/skelet/error.log \
    skelet.wsgi:application

Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
mkdir -p /var/www/skelet/run /var/log/skelet
chown -R www-data:www-data /var/www/skelet /var/log/skelet
chmod 755 /var/www/skelet/.venv/bin/gunicorn

systemctl daemon-reload
systemctl enable skelet
systemctl start skelet
systemctl status skelet

三、Nginx 配置

# /etc/nginx/sites-available/skelet
server {
    listen 80;
    server_name yourdomain.com;
    client_max_body_size 20M;

    location /static/ {
        alias /var/www/skelet/static/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    location /media/ {
        alias /var/www/skelet/media/;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/var/www/skelet/run/gunicorn.sock;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
ln -s /etc/nginx/sites-available/skelet /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default
nginx -t
systemctl reload nginx

四、SQLite 上线检查(T-303)

JSON1 支持验证

python -c "import sqlite3; c=sqlite3.connect(':memory:'); c.execute('SELECT json(\'{\"a\":1}\')'); print('JSON1 supported')"

启用 WAL 模式

python manage.py dbshell
    .journal_mode WAL;
    .quit

验证:

python manage.py dbshell -- -cmd "PRAGMA journal_mode;"
# 输出 wal

备份策略

# 每日备份脚本(crontab:0 3 * * * /root/backup-skelet.sh)

#!/bin/bash
BACKUP_DIR=/var/backups/skelet
mkdir -p "$BACKUP_DIR"
DATE=$(date +%Y%m%d-%H%M%S)

# 备份数据库(生产环境先暂停写入)
sqlite3 /var/www/skelet/db.sqlite3 ".backup '$BACKUP_DIR/db-$DATE.sqlite3'"

# 备份 media 文件
tar -czf "$BACKUP_DIR/media-$DATE.tar.gz" -C /var/www/skelet media/

# 保留最近 30 天备份
find "$BACKUP_DIR" -name 'db-*.sqlite3' -mtime +30 -delete
find "$BACKUP_DIR" -name 'media-*.tar.gz' -mtime +30 -delete

PostgreSQL 迁移触发条件

当前使用 SQLite(读多写少场景足够)。当出现以下任一情况时,应迁移 PostgreSQL:

  • 后台多人同时编辑时出现 database is locked
  • 预计日均写入请求超过 100 次
  • 索引无法加速复杂筛选查询
  • 上线了用户提交、评论、收藏、会员等前台写入功能

迁移方式:

# 1. 使用 pgloader 迁移数据
# 2. 更新 settings/production.py 数据库配置至 PostgreSQL
# 3. 设置环境变量 DATABASE_URL=postgres://user:pass@host/db

五、日常维护

重启应用

systemctl restart skelet

重新加载 Nginx

systemctl reload nginx

回滚部署

cd /var/www/skelet
git revert HEAD
systemctl restart skelet

查看日志

journalctl -u skelet -n 50
tail -f /var/log/skelet/error.log