diff --git a/spanish-diary项目部署方案.md b/spanish-diary项目部署方案.md new file mode 100644 index 0000000..52de90e --- /dev/null +++ b/spanish-diary项目部署方案.md @@ -0,0 +1,373 @@ +# Spanish Diary 项目部署方案 + +## 1. 部署架构 + +`spanish-diary` 由前端静态页面和 Flask 后端组成,后端同时负责 API 和静态页面托管,因此只需要把 Python 服务跑起来即可。 + +推荐生产部署方式: + +```text +Ubuntu + Python venv + Gunicorn + systemd + Nginx +``` + +不依赖 Docker,避免国内服务器无法拉取 Docker Hub 镜像的问题。 + +## 2. 项目目录说明 + +```text +/opt/spanish-diary +├── index.html # 主页面 +├── login.html # 登录/注册 +├── admin.html # 管理员用户管理 +├── knowledge.html # 知识库首页 +├── knowledge/ # 知识库分类页面 +├── app.js # 前端应用逻辑 +├── api.js # 后端 API 客户端 +├── server/ # Flask 后端 +│ ├── app.py # 应用入口 +│ ├── requirements.txt # Python 依赖 +│ ├── db.py # SQLite 初始化 +│ └── data/ # SQLite 数据库目录 +└── venv/ # Python 虚拟环境 +``` + +SQLite 数据库路径: + +```text +/opt/spanish-diary/server/data/spanish_diary.db +``` + +首次启动时后端会自动创建数据库、数据表和管理员账号。 + +## 3. Windows 本地运行 + +Windows PowerShell: + +```powershell +cd C:\Users\Administrator\Documents\Codex\2026-07-30\build-web-apps-plugin-build-web\spanish-diary +python -m venv .venv +.\.venv\Scripts\Activate.ps1 +python -m pip install -r server\requirements.txt +python server\app.py +``` + +访问: + +```text +http://localhost:5000 +``` + +默认管理员: + +```text +用户名:admin +密码:admin123 +``` + +## 4. Ubuntu 生产部署 + +### 4.1 安装基础软件 + +```bash +sudo apt update +sudo apt install -y git python3-venv python3-pip nginx +``` + +### 4.2 创建运行用户并拉取代码 + +```bash +sudo useradd --system --no-create-home --home /opt/spanish-diary --shell /usr/sbin/nologin spanish-diary || true +sudo mkdir -p /opt/spanish-diary +sudo git clone https://git.youzhilian.cn/guoqingshan/spanish-diary.git /opt/spanish-diary +``` + +如果仓库是私有的,在服务器上使用 Gitea Access Token 作为密码,或配置 SSH Key。不要把令牌长期写入 shell 历史。 + +### 4.3 创建 Python 虚拟环境 + +```bash +cd /opt/spanish-diary +sudo python3 -m venv venv +sudo venv/bin/pip install --upgrade pip +sudo venv/bin/pip install -r server/requirements.txt +sudo venv/bin/pip install gunicorn +sudo chown -R spanish-diary:spanish-diary /opt/spanish-diary +``` + +### 4.4 生成 SECRET_KEY + +```bash +python3 -c "import secrets; print(secrets.token_hex(32))" +``` + +把输出保存下来,后面写入 systemd 服务。 + +### 4.5 手动测试启动 + +```bash +cd /opt/spanish-diary +sudo -u spanish-diary env SECRET_KEY='替换为生成的密钥' \ + /opt/spanish-diary/venv/bin/gunicorn \ + --workers 2 --threads 2 \ + --bind 127.0.0.1:5000 \ + server.app:app +``` + +另开一个终端验证: + +```bash +curl http://127.0.0.1:5000/ +``` + +### 4.6 创建 systemd 服务 + +```bash +sudo tee /etc/systemd/system/spanish-diary.service > /dev/null <<'EOF' +[Unit] +Description=Spanish Diary Flask App +After=network.target + +[Service] +User=spanish-diary +Group=spanish-diary +WorkingDirectory=/opt/spanish-diary +Environment=SECRET_KEY=替换为生成的密钥 +Environment=COOKIE_SECURE=0 +Environment=PYTHONUNBUFFERED=1 +ExecStart=/opt/spanish-diary/venv/bin/gunicorn --workers 2 --threads 2 --bind 127.0.0.1:5000 server.app:app +Restart=always +RestartSec=3 + +[Install] +WantedBy=multi-user.target +EOF + +sudo systemctl daemon-reload +sudo systemctl enable --now spanish-diary +sudo systemctl status spanish-diary +``` + +查看日志: + +```bash +sudo journalctl -u spanish-diary -f +``` + +常用命令: + +```bash +sudo systemctl start spanish-diary +sudo systemctl stop spanish-diary +sudo systemctl restart spanish-diary +``` + +### 4.7 配置 Nginx 反向代理 + +```bash +sudo tee /etc/nginx/sites-available/spanish-diary > /dev/null <<'EOF' +server { + listen 80; + server_name your-domain.com; + + client_max_body_size 2m; + + location / { + proxy_pass http://127.0.0.1:5000; + 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; + } +} +EOF + +sudo ln -s /etc/nginx/sites-available/spanish-diary /etc/nginx/sites-enabled/ +sudo nginx -t +sudo systemctl reload nginx +``` + +没有域名时,可以先把 `server_name` 改为 `_`,使用服务器 IP 访问。 + +### 4.8 配置 HTTPS + +```bash +sudo apt install -y certbot python3-certbot-nginx +sudo certbot --nginx -d your-domain.com +``` + +启用 HTTPS 后,把 systemd 服务中的环境变量改为: + +```ini +Environment=COOKIE_SECURE=1 +``` + +然后重启: + +```bash +sudo systemctl daemon-reload +sudo systemctl restart spanish-diary +``` + +### 4.9 配置防火墙 + +```bash +sudo ufw allow OpenSSH +sudo ufw allow 80/tcp +sudo ufw allow 443/tcp +sudo ufw enable +``` + +## 5. 数据库备份与恢复 + +### 5.1 备份 + +```bash +sudo mkdir -p /backup +sudo systemctl stop spanish-diary +sudo cp /opt/spanish-diary/server/data/spanish_diary.db /backup/spanish-diary-$(date +%F).db +sudo systemctl start spanish-diary +``` + +建议把 `/backup` 同步到其他服务器、对象存储或本机。 + +### 5.2 恢复 + +```bash +sudo systemctl stop spanish-diary +sudo cp /backup/spanish-diary-YYYY-MM-DD.db /opt/spanish-diary/server/data/spanish_diary.db +sudo chown spanish-diary:spanish-diary /opt/spanish-diary/server/data/spanish_diary.db +sudo systemctl start spanish-diary +``` + +## 6. 升级项目 + +```bash +sudo -u spanish-diary git -C /opt/spanish-diary pull origin master +sudo systemctl restart spanish-diary +``` + +升级前建议先备份数据库。 + +## 7. 修改默认管理员密码 + +项目当前没有管理员修改密码页面,生产环境首次启动后建议手动修改 `admin` 密码。 + +```bash +cd /opt/spanish-diary +sudo -u spanish-diary venv/bin/python - <<'EOF' +import sqlite3 +from werkzeug.security import generate_password_hash + +conn = sqlite3.connect("server/data/spanish_diary.db") +conn.execute( + "UPDATE users SET password_hash=? WHERE username='admin'", + (generate_password_hash("你的新密码"),), +) +conn.commit() +conn.close() +print("admin password updated") +EOF +``` + +## 8. 接入翻译服务 + +项目支持三种翻译方式: + +- 本地词典:前端完成,无需额外服务 +- MyMemory:免费在线接口,无需部署 +- 自定义接口:可对接自建 LibreTranslate + +如果使用 LibreTranslate,请先参考百科中的《LibreTranslate Conda 部署方案(Ubuntu)》。 + +在项目“翻译设置”中选择“自定义接口”: + +```text +接口地址:http://127.0.0.1:5001/translate +接口密钥:你的APIKey +``` + +扩展配置: + +```json +{ + "result_key": "translatedText", + "headers": { + "Authorization": "Bearer 你的APIKey" + } +} +``` + +## 9. 环境变量说明 + +```text +SECRET_KEY 会话加密密钥,必须设置为随机长字符串 +COOKIE_SECURE 使用 HTTPS 时设置为 1 +PYTHONUNBUFFERED 设置为 1,便于日志实时输出 +``` + +## 10. 常见问题 + +### 10.1 服务启动失败 + +查看日志: + +```bash +sudo journalctl -u spanish-diary -e +``` + +检查代码目录和数据库目录权限: + +```bash +sudo chown -R spanish-diary:spanish-diary /opt/spanish-diary +sudo systemctl restart spanish-diary +``` + +### 10.2 Gunicorn 找不到 server.app + +确保工作目录是项目根目录: + +```bash +cd /opt/spanish-diary +``` + +### 10.3 登录后会话失效 + +确认 `SECRET_KEY` 已设置,并且没有频繁更换。 + +### 10.4 HTTPS 下无法登录或会话不稳定 + +确认 systemd 中已设置: + +```ini +Environment=COOKIE_SECURE=1 +``` + +### 10.5 端口 5000 被占用 + +修改 Gunicorn 绑定端口: + +```bash +--bind 127.0.0.1:5001 +``` + +同时修改 Nginx 的 `proxy_pass`: + +```nginx +proxy_pass http://127.0.0.1:5001; +``` + +## 11. 部署完成检查 + +```bash +curl http://127.0.0.1:5000/ +sudo systemctl is-active spanish-diary +sudo nginx -t +``` + +浏览器访问: + +```text +http://your-domain.com +``` + +使用默认管理员登录后,应立即修改管理员密码。