Phase 3: T-301~T-304 SEO/部署/SQLite/统计/MVP验收完成(42 tests)
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
# 部署指南
|
||||
|
||||
> 适用于 2 核 2G VPS(Ubuntu 22.04/24.04),Gunicorn + Nginx + SQLite。
|
||||
|
||||
## 前置条件
|
||||
|
||||
```bash
|
||||
# 确保系统已安装
|
||||
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
|
||||
```
|
||||
|
||||
## 一、应用部署
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# /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
|
||||
```
|
||||
|
||||
```bash
|
||||
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 配置
|
||||
|
||||
```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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
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 支持验证
|
||||
|
||||
```bash
|
||||
python -c "import sqlite3; c=sqlite3.connect(':memory:'); c.execute('SELECT json(\'{\"a\":1}\')'); print('JSON1 supported')"
|
||||
```
|
||||
|
||||
### 启用 WAL 模式
|
||||
|
||||
```bash
|
||||
python manage.py dbshell
|
||||
.journal_mode WAL;
|
||||
.quit
|
||||
```
|
||||
|
||||
验证:
|
||||
|
||||
```bash
|
||||
python manage.py dbshell -- -cmd "PRAGMA journal_mode;"
|
||||
# 输出 wal
|
||||
```
|
||||
|
||||
### 备份策略
|
||||
|
||||
```bash
|
||||
# 每日备份脚本(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 次
|
||||
- 索引无法加速复杂筛选查询
|
||||
- 上线了用户提交、评论、收藏、会员等前台写入功能
|
||||
|
||||
迁移方式:
|
||||
|
||||
```bash
|
||||
# 1. 使用 pgloader 迁移数据
|
||||
# 2. 更新 settings/production.py 数据库配置至 PostgreSQL
|
||||
# 3. 设置环境变量 DATABASE_URL=postgres://user:pass@host/db
|
||||
```
|
||||
|
||||
## 五、日常维护
|
||||
|
||||
### 重启应用
|
||||
|
||||
```bash
|
||||
systemctl restart skelet
|
||||
```
|
||||
|
||||
### 重新加载 Nginx
|
||||
|
||||
```bash
|
||||
systemctl reload nginx
|
||||
```
|
||||
|
||||
### 回滚部署
|
||||
|
||||
```bash
|
||||
cd /var/www/skelet
|
||||
git revert HEAD
|
||||
systemctl restart skelet
|
||||
```
|
||||
|
||||
### 查看日志
|
||||
|
||||
```bash
|
||||
journalctl -u skelet -n 50
|
||||
tail -f /var/log/skelet/error.log
|
||||
```
|
||||
Reference in New Issue
Block a user