跳转至

Web项目工程化规范 — 运维安全与文档

核心知识点速查表

知识点说明
八、数据库备份见对应章节
九、进程管理与监控见对应章节
十、HTTPS 与域名见对应章节
十一、安全加固见对应章节
十二、文档见对应章节
功能特性见对应章节
快速开始见对应章节
项目结构见对应章节

八、数据库备份

为什么需要

不备份的后果:一行误操作的 SQL(DELETE FROM users——忘了 WHERE),所有用户数据永久丢失。

8.1 SQLite 备份策略 [必须]

#!/bin/bash
# /opt/t2d-api/scripts/backup_db.sh —— SQLite 数据库备份脚本

# === 配置 ===
DB_PATH="/opt/t2d-api/data.db"               # 数据库文件路径
BACKUP_DIR="/opt/t2d-api/backups"            # 本地备份目录
DATE=$(date +%Y%m%d_%H%M%S)                 # 时间戳(如 20260504_143000)
BACKUP_FILE="$BACKUP_DIR/data_${DATE}.db"    # 备份文件名

# === 创建备份目录 ===
mkdir -p "$BACKUP_DIR"                       # -p: 目录已存在也不报错

# === 使用 SQLite 的 .backup 命令(不锁表、一致性有保障) ===
sqlite3 "$DB_PATH" ".backup '$BACKUP_FILE'"  # 官方推荐的备份方式
# 不要用 cp 命令!正在写入时 cp 可能拿到损坏的文件

# === 压缩 ===
gzip "$BACKUP_FILE"                          # 压缩,节省空间
echo "[$(date)] 备份成功: ${BACKUP_FILE}.gz"

# === 删除 7 天前的旧备份 ===
find "$BACKUP_DIR" -name "*.gz" -mtime +7 -delete  # 只保留 7 天

8.2 cron 定时任务 [必须]

# 编辑定时任务
crontab -e                                   # 打开当前用户的 cron 编辑器

# 添加以下行(每天凌晨 3 点执行备份)
0 3 * * * /opt/t2d-api/scripts/backup_db.sh >> /opt/t2d-api/logs/backup.log 2>&1
# 分 时 日 月 周 命令
# 0  3  *  *  *  = 每天 03:00
# >> 追加输出到日志文件
# 2>&1 把错误也输出到同一个文件

# 验证 cron 是否生效
crontab -l                                   # 列出所有定时任务

8.3 备份到远程(异地容灾)[推荐]

# 方案 1:rsync 同步到远程服务器
rsync -avz /opt/t2d-api/backups/ user@backup-server:/backups/t2d-api/
# -a 归档模式  -v 详细输出  -z 压缩传输

# 方案 2:上传到对象存储(阿里云 OSS / 腾讯 COS)
# 安装阿里云 CLI
pip install oss2
# 在备份脚本最后添加上传命令:
# python /opt/t2d-api/scripts/upload_to_oss.py "$BACKUP_FILE.gz"

# 方案 3:rclone(通用云存储同步工具,支持几十种云服务)
rclone copy /opt/t2d-api/backups/ remote:t2d-backups/ --max-age 7d

九、进程管理与监控

为什么需要

不做进程管理的后果: - 服务器重启后你的 FastAPI 不会自动启动 - 进程崩溃了没人知道,直到用户找你 - 内存泄漏慢慢把服务器搞崩

9.1 systemd service 配置 [必须]

# /etc/systemd/system/t2d-api.service —— systemd 服务单元文件
[Unit]
Description=T2D API Service                  # 服务描述
After=network.target                         # 等网络就绪后再启动

[Service]
Type=notify                                  # Gunicorn 支持 systemd 通知
User=www-data                                # 运行用户(不要用 root!)
Group=www-data                               # 运行用户组
WorkingDirectory=/opt/t2d-api                # 工作目录

# 用 Gunicorn 启动 FastAPI(UvicornWorker 处理异步请求)
ExecStart=/opt/t2d-api/.venv/bin/gunicorn \
    app.main:app \
    --worker-class uvicorn.workers.UvicornWorker \
    --workers 3 \
    --bind unix:/opt/t2d-api/gunicorn.sock \
    --access-logfile - \
    --error-logfile - \
    --max-requests 1000 \
    --max-requests-jitter 50 \
    --graceful-timeout 30
# --worker-class     使用 Uvicorn 异步 worker
# --workers 3        启动 3 个 worker 进程(2*CPU+1)
# --bind unix:...    用 Unix Socket 通信(比 TCP 快)
# --max-requests     处理 1000 个请求后重启 worker(防内存泄漏)
# --max-requests-jitter  随机偏移,防止所有 worker 同时重启
# --graceful-timeout     优雅关闭等待时间

# 优雅重载(发送 HUP 信号,不断连接)
ExecReload=/bin/kill -s HUP $MAINPID

# 自动重启配置
Restart=on-failure                           # 异常退出时自动重启
RestartSec=10                                # 重启前等 10 秒
StartLimitBurst=5                            # 最多连续重启 5 次
StartLimitIntervalSec=60                     # 60 秒内

# 日志
StandardOutput=journal                       # 标准输出写入 systemd 日志
StandardError=journal                        # 错误输出也写入

# 安全加固
NoNewPrivileges=true                         # 禁止获取新特权
PrivateTmp=true                              # 使用独立的 /tmp

[Install]
WantedBy=multi-user.target                   # 开机自动启动
# 加载并启动服务
sudo systemctl daemon-reload                 # 重新加载 service 文件
sudo systemctl enable t2d-api                # 设为开机自启
sudo systemctl start t2d-api                 # 启动服务

# 常用管理命令
sudo systemctl status t2d-api                # 查看状态
sudo systemctl reload t2d-api                # 优雅重载(不断线)
sudo systemctl restart t2d-api               # 完全重启
sudo journalctl -u t2d-api -f               # 实时查看日志(-f = follow)
sudo journalctl -u t2d-api --since today     # 查看今天的日志

9.2 健康检查端点 [必须]

# app/api/health.py —— 健康检查接口
from fastapi import APIRouter
from datetime import datetime

router = APIRouter(tags=["健康检查"])

@router.get("/health")
async def health_check():
    """基础存活检查 —— 进程还活着吗"""
    return {"status": "ok", "timestamp": datetime.now().isoformat()}

@router.get("/health/ready")
async def readiness_check():
    """就绪检查 —— 能正常处理请求吗(检查数据库等依赖)"""
    checks = {}
    try:
        # 检查数据库连接
        from app.core.database import engine
        async with engine.connect() as conn:
            await conn.execute("SELECT 1")   # 最简单的数据库探活
        checks["database"] = "ok"
    except Exception as e:
        checks["database"] = f"error: {e}"
        return {"status": "unhealthy", "checks": checks}

    return {"status": "healthy", "checks": checks}

9.3 外部监控 [推荐]

工具费用功能
UptimeRobot免费 50 个监控每 5 分钟检查一次,宕机发邮件/微信
Better Uptime免费版可用更好看的状态页
自建 cron 检查免费curl 你的 /health 端点

在 UptimeRobot 中添加: - Monitor Type: HTTP(s) - URL: https://your-domain.com/health - Monitoring Interval: 5 minutes - Alert Contacts: 你的邮箱/Telegram


十、HTTPS 与域名

为什么需要

不用 HTTPS 的后果: - 用户密码明文传输,同一个 WiFi 的人都能截获 - 浏览器显示"不安全"大红警告——用户直接跑了 - 搜索引擎会降低你网站的排名

10.1 Nginx 反向代理配置 [必须]

# /etc/nginx/sites-available/t2d-api —— Nginx 配置
# 第一步:先配 HTTP(让 Certbot 能验证域名)

server {
    listen 80;                               # 监听 80 端口
    server_name your-domain.com;             # 你的域名

    # Certbot 域名验证用的路径
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;               # Certbot 验证文件存放目录
    }

    # 其他所有请求转发给 FastAPI
    location / {
        proxy_pass http://unix:/opt/t2d-api/gunicorn.sock;  # Unix Socket
        proxy_set_header Host $http_host;                    # 传递原始域名
        proxy_set_header X-Real-IP $remote_addr;             # 真实客户端 IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;          # http 或 https
        proxy_read_timeout 300s;                             # 长任务超时时间
    }
}
# 启用站点配置
sudo ln -s /etc/nginx/sites-available/t2d-api /etc/nginx/sites-enabled/
sudo nginx -t                                # 测试配置语法是否正确
sudo systemctl reload nginx                  # 重新加载配置

10.2 Let's Encrypt (Certbot) 配置 HTTPS [必须]

# 安装 Certbot
sudo apt update
sudo snap install --classic certbot          # 用 snap 安装(官方推荐)
sudo ln -s /snap/bin/certbot /usr/bin/certbot  # 创建快捷命令

# 申请证书(Certbot 会自动修改 Nginx 配置)
sudo certbot --nginx -d your-domain.com      # 自动配置 HTTPS
# Certbot 会:
# 1. 验证你对域名的控制权
# 2. 下载证书到 /etc/letsencrypt/live/your-domain.com/
# 3. 自动修改 Nginx 配置,添加 SSL 相关指令
# 4. 添加 HTTP→HTTPS 自动跳转

# 验证自动续期
sudo certbot renew --dry-run                 # 模拟续期(不真正执行)
# Let's Encrypt 证书有效期 90 天,Certbot 自动续期

Certbot 自动修改后的 Nginx 配置大致是:

# Certbot 自动添加的 HTTPS 配置(不需要手写)
server {
    listen 443 ssl;
    server_name your-domain.com;

    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://unix:/opt/t2d-api/gunicorn.sock;
        proxy_set_header Host $http_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;
    }
}

# HTTP 自动跳转到 HTTPS
server {
    listen 80;
    server_name your-domain.com;
    return 301 https://$host$request_uri;    # 永久重定向到 HTTPS
}

10.3 Cloudflare 配置(国内加速 + 防护)[推荐]

如果域名放在 Cloudflare: 1. 注册 Cloudflare → 添加你的域名 2. 修改域名 DNS 服务器为 Cloudflare 提供的 3. SSL/TLS 模式选 Full (Strict)(后端有证书时最安全) 4. 开启 "Always Use HTTPS" 5. 好处:CDN 加速、DDoS 防护、免费 SSL


十一、安全加固

为什么需要

不做安全加固的后果: - 服务器被黑客入侵当矿机 - 数据库被拖库,用户数据泄露 - SSH 被暴力破解(每天数千次尝试)

11.1 防火墙(UFW)[必须]

# 安装并配置 UFW(Uncomplicated Firewall)
sudo apt install ufw                         # Ubuntu 通常已预装

# 设置默认策略
sudo ufw default deny incoming               # 默认拒绝所有入站连接
sudo ufw default allow outgoing              # 允许所有出站连接

# 放行必要端口
sudo ufw allow 22/tcp                        # SSH(如果改了端口就改这里)
sudo ufw allow 80/tcp                        # HTTP
sudo ufw allow 443/tcp                       # HTTPS

# 启用防火墙
sudo ufw enable                              # 启用(会提示可能断开 SSH,确认即可)
sudo ufw status verbose                      # 查看规则

# 【更安全】限制 SSH 只允许特定 IP
sudo ufw delete allow 22/tcp                 # 先删掉通用规则
sudo ufw allow from 你的固定IP to any port 22  # 只允许你的 IP 连 SSH

11.2 SSH 安全加固 [必须]

# 编辑 SSH 配置
sudo nano /etc/ssh/sshd_config

# 以下是建议修改的配置项:
Port 2222                                    # 改掉默认 22 端口(减少扫描噪音)
PermitRootLogin no                           # 禁止 root 直接登录
PasswordAuthentication no                    # 禁用密码登录(只允许密钥)
PubkeyAuthentication yes                     # 启用公钥认证
MaxAuthTries 3                               # 最多尝试 3 次
ClientAliveInterval 300                      # 5 分钟无操作断开
ClientAliveCountMax 2                        # 发 2 次心跳包无响应断开

# 重启 SSH 服务(先开另一个终端测试能否登录!)
sudo systemctl restart sshd

重要提醒:修改 SSH 配置前,一定要保持一个已连接的终端窗口。如果配置出错导致无法登录,你还能用这个窗口改回来。

11.3 Fail2Ban [推荐]

# 安装
sudo apt install fail2ban                    # 安装 fail2ban

# 创建本地配置(不要直接改 jail.conf)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# 编辑 jail.local,找到 [sshd] 段:
sudo nano /etc/fail2ban/jail.local
# /etc/fail2ban/jail.local 关键配置
[DEFAULT]
bantime = 86400                              # 封禁 24 小时(秒)
findtime = 600                               # 10 分钟内
maxretry = 5                                 # 失败 5 次就封

[sshd]
enabled = true                               # 启用 SSH 防护
port = 2222                                  # 你的 SSH 端口(如果改了的话)
banaction = ufw                              # 用 UFW 执行封禁(和防火墙联动)
logpath = /var/log/auth.log                  # SSH 日志路径

# 可选:保护 Nginx(防止恶意请求)
[nginx-http-auth]
enabled = true
# 启动并查看状态
sudo systemctl enable fail2ban               # 开机自启
sudo systemctl start fail2ban
sudo fail2ban-client status sshd             # 查看 SSH 防护状态
# 会显示被封的 IP 数量和列表

11.4 安全响应头 [推荐]

在 FastAPI 中添加安全头中间件:

# app/middleware/security.py —— 安全响应头中间件
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import Response

class SecurityHeadersMiddleware(BaseHTTPMiddleware):
    """给每个响应添加安全头"""
    async def dispatch(self, request: Request, call_next):
        response: Response = await call_next(request)

        # 防止 MIME 类型嗅探攻击
        response.headers["X-Content-Type-Options"] = "nosniff"
        # 防止网页被嵌入 iframe(点击劫持防护)
        response.headers["X-Frame-Options"] = "DENY"
        # 控制 Referer 头泄露信息
        response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin"
        # 强制 HTTPS(开启后浏览器会记住,1年内都走 HTTPS)
        response.headers["Strict-Transport-Security"] = (
            "max-age=31536000; includeSubDomains"
        )
        # 禁用危险的浏览器功能
        response.headers["Permissions-Policy"] = (
            "camera=(), microphone=(), geolocation=()"
        )

        return response
# app/main.py 中注册中间件
from app.middleware.security import SecurityHeadersMiddleware
app.add_middleware(SecurityHeadersMiddleware)

11.5 自动安全更新 [推荐]

# 启用自动安全更新
sudo apt install unattended-upgrades          # 安装自动更新工具
sudo dpkg-reconfigure unattended-upgrades     # 交互式配置,选 Yes

# 检查是否开启
cat /etc/apt/apt.conf.d/20auto-upgrades
# 应该显示:
# APT::Periodic::Unattended-Upgrade "1";

十二、文档

为什么需要

不写文档的后果: - 三个月后你自己都忘了这个接口怎么用 - 新同事接手该项目,看不懂就从头写 - API 没有文档,前端同事天天找你问参数格式

12.1 README 规范 [必须]

一个好的 README 至少包含:

# T2D-API:2型糖尿病肠道菌群分析平台

> 基于 FastAPI 的宏基因组分析数据服务化平台

## 功能特性
- 物种丰度查询与可视化
- 样本上传与自动分析
- 多样性指数计算

## 快速开始

### 环境要求
- Python 3.12+
- SQLite 3.x

### 安装与运行
```bash
git clone git@github.com:xxx/t2d-api.git
cd t2d-api
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env  # 编辑 .env 填入配置
uvicorn app.main:app --reload

API 文档

启动后访问:http://localhost:8000/docs

项目结构

app/
├── main.py          # 应用入口
├── api/             # 路由
├── services/        # 业务逻辑
├── models/          # 数据模型
├── schemas/         # 请求/响应模型
└── core/            # 配置、数据库

部署

详见 部署文档

许可证

MIT License

### 12.2 API 文档(FastAPI 自带)[必须]

FastAPI 的杀手级特性:**自动生成交互式 API 文档**。

```python
# 只要在代码里写好类型标注和描述,文档自动生成
from fastapi import FastAPI, Query

app = FastAPI(
    title="T2D-API",                         # 文档页标题
    description="2型糖尿病肠道菌群分析平台",   # 描述
    version="1.0.0",                          # 版本号
)

@app.get(
    "/api/v1/species",
    summary="查询物种列表",                     # 接口概要
    description="支持按名称模糊搜索和分页",      # 详细描述
)
async def list_species(
    keyword: str = Query(                     # Query 参数
        default=None,
        description="物种名称关键词(支持模糊搜索)",
        examples=["Bacteroides"],             # 示例值
    ),
    page: int = Query(default=1, ge=1, description="页码"),
    size: int = Query(default=20, ge=1, le=100, description="每页数量"),
):
    ...

访问两个自动生成的文档页面: - Swagger UIhttp://localhost:8000/docs(交互式,能直接测试接口) - ReDochttp://localhost:8000/redoc(更好看的只读文档)

12.3 CHANGELOG [推荐]

# 用 commitizen 自动从提交记录生成 CHANGELOG
cz changelog                                 # 自动生成 CHANGELOG.md
# 原理:根据 feat/fix/refactor 等类型的提交信息,自动分类整理

生成的 CHANGELOG.md 大致长这样:

## 1.1.0 (2026-05-04)

### Features
- 新增物种丰度查询接口 (#12)
- 支持批量样本上传 (#15)

### Bug Fixes
- 修复大文件上传超时问题 (#13)
- 修复分页查询总数不准的问题 (#14)

十三、依赖管理

为什么需要

不管理依赖的后果: - "我电脑上能跑,服务器上跑不了"——版本不一致 - 某个依赖有安全漏洞——你完全不知道 - pip install xxx 装了最新版但不兼容——整个项目跑崩

13.1 requirements.txt vs pyproject.toml 对比

对比项requirements.txtpyproject.toml
格式纯文本,一行一个包TOML 结构化
标准化非标准PEP 621 标准
工具配置不支持可以集中放 pytest/ruff 等配置
适合简单项目、部署正式项目(2025 推荐)

13.2 pyproject.toml 完整示例 [推荐]

# pyproject.toml —— 项目的中央配置文件(一个文件管所有)

[build-system]
requires = ["hatchling"]                     # 构建后端
build-backend = "hatchling.build"            # 指定构建工具

[project]
name = "t2d-api"                             # 项目名
version = "1.0.0"                            # 版本号
description = "2型糖尿病肠道菌群分析平台"      # 描述
requires-python = ">=3.12"                   # Python 版本要求
license = {text = "MIT"}                     # 许可证
authors = [
    {name = "你的名字", email = "your@email.com"},
]

# === 生产依赖 ===
dependencies = [
    "fastapi>=0.115",                        # Web 框架
    "uvicorn[standard]>=0.32",               # ASGI 服务器
    "gunicorn>=23.0",                        # 进程管理器
    "pydantic-settings>=2.6",                # 配置管理
    "sqlalchemy>=2.0",                       # ORM
    "aiosqlite>=0.20",                       # SQLite 异步驱动
    "loguru>=0.7",                           # 日志
    "python-multipart>=0.0.12",              # 文件上传支持
]

# === 开发/测试依赖(两种写法任选其一) ===

# 写法 1(传统,兼容性好):[project.optional-dependencies]
# 安装方式:pip install -e ".[dev]"
[project.optional-dependencies]
dev = [
    "pytest>=8.0",                           # 测试框架
    "pytest-cov>=6.0",                       # 测试覆盖率
    "pytest-asyncio>=0.24",                  # 异步测试支持
    "httpx>=0.27",                           # 异步 HTTP 客户端(测试用)
    "ruff>=0.8",                             # 代码检查+格式化
    "pre-commit>=4.0",                       # Git 钩子
    "commitizen>=4.0",                       # 提交规范
    "pip-audit>=2.7",                        # 依赖漏洞扫描
]

# 写法 2(2025+ 新标准,PEP 735):[dependency-groups]
# uv 和 pip 24.3+ 原生支持,安装方式:uv add --dev pytest
# [dependency-groups]
# dev = [
#     "pytest>=8.0",
#     "pytest-cov>=6.0",
#     "pytest-asyncio>=0.24",
#     "httpx>=0.27",
#     "ruff>=0.8",
#     "pre-commit>=4.0",
#     "commitizen>=4.0",
#     "pip-audit>=2.7",
# ]
# 区别:[dependency-groups] 是专门给开发工具用的,不会被打包发布
# 如果用 uv,它会自动写入 [dependency-groups] 而非 [project.optional-dependencies]

# === Ruff 配置(一个工具替代 Black + Flake8 + isort) ===
[tool.ruff]
target-version = "py312"                     # 目标 Python 版本
line-length = 120                            # 行宽限制

[tool.ruff.lint]
select = [
    "E",                                     # pycodestyle errors
    "W",                                     # pycodestyle warnings
    "F",                                     # pyflakes
    "I",                                     # isort(import 排序)
    "B",                                     # flake8-bugbear
    "S",                                     # flake8-bandit(安全检查)
    "UP",                                    # pyupgrade(语法升级建议)
]

# === pytest 配置 ===
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-v --cov=app --cov-report=term-missing"
asyncio_mode = "auto"

# === 覆盖率配置 ===
[tool.coverage.report]
fail_under = 80
show_missing = true

# === commitizen 配置 ===
[tool.commitizen]
name = "cz_conventional_commits"             # 使用 conventional commits 规范
version = "1.0.0"                            # 和 [project] 中的 version 保持一致
tag_format = "v$version"                     # 标签格式:v1.0.0

13.3 依赖锁定 [推荐]

# === 方案 1(推荐):uv lock ===
# uv 项目模式自动维护 uv.lock 锁文件
uv lock                                      # 手动生成/更新 uv.lock
uv sync                                      # 从 uv.lock 精确安装(保证一致性)
uv run pytest                                # uv run 每次执行前自动检查并同步
# uv.lock 是跨平台的,包含每个平台的精确依赖树
# 【重要】uv.lock 必须提交到 Git,它才是真正的"锁定"

# 如果生产环境不用 uv,可以导出传统 requirements.txt:
uv export --format requirements-txt > requirements.txt  # 从 uv.lock 导出

# === 方案 2:pip-compile(pip-tools 提供,传统方案) ===
pip install pip-tools                        # 安装 pip-tools
pip-compile pyproject.toml -o requirements.txt  # 从 pyproject.toml 生成锁定文件
# 锁定文件包含精确版本号,确保不同环境安装完全一致的依赖

# 从锁定文件安装(确保版本一致)
pip install -r requirements.txt              # 精确安装锁定版本

为什么要锁定? pyproject.toml 写的是 fastapi>=0.115(范围),锁文件写的是 fastapi==0.115.6(精确版本)。没有锁文件,两个人 pip install 可能装出不同版本,导致"我电脑上能跑"的经典问题。

13.4 安全漏洞扫描 [推荐]

# pip-audit:扫描已安装的包是否有已知漏洞
pip install pip-audit                        # 安装
pip-audit                                    # 扫描当前环境
# 输出示例:
# Found 1 known vulnerability in 1 package
# Name    Version  ID               Fix Versions
# ------- -------- ---------------  ------------
# pillow  9.5.0    PYSEC-2023-175   10.0.1

# 自动修复(升级有漏洞的包)
pip-audit --fix                              # 自动升级到修复版本

# 在 CI 中使用
pip-audit -r requirements.txt                # 扫描 requirements.txt 中的依赖

在 GitHub Actions 中集成漏洞扫描:

# 在 CI 的 test job 中添加一步
      - name: Audit dependencies              # 依赖安全扫描
        run: pip-audit -r requirements.txt

13.5 工具对比总结

工具用途是否免费推荐度
pip-audit依赖漏洞扫描免费开源首选
Safety依赖漏洞扫描免费版有限制备选(付费版数据更全)
Ruff代码检查+格式化免费开源必装(替代 Black+Flake8+isort)
uv包管理器免费开源推荐(替代 pip,快 10-100 倍)
pip-tools依赖锁定免费开源稳妥之选

快速参考:13 项工程化规范优先级

#规范必须推荐进阶
1Git 初始化 + .gitignorex
1Conventional Commitsx
1Tag 版本标记x
2分支策略(GitHub Flow)x
2保护主分支x
3SSH Key + 远程仓库x
3双平台推送x
4.env 环境分离x
4虚拟环境x
5CI/CD(GitHub Actions)x
5部署脚本x
6单元测试 + pytestx
6测试覆盖率 80%x
7日志系统(loguru)x
7日志轮转x
8数据库备份脚本x
8cron 定时备份x
8远程备份x
9systemd 服务x
9健康检查端点x
9外部监控x
10Nginx 反向代理x
10HTTPS (Certbot)x
10Cloudflarex
11UFW 防火墙x
11SSH 加固x
11Fail2Banx
11安全响应头x
12READMEx
12API 文档(自动生成)x
12CHANGELOGx
13pyproject.tomlx
13依赖锁定x
13漏洞扫描x

推荐的实施顺序

如果你是从零开始,按这个顺序来:

第 1 天:Git 初始化 + .gitignore + 远程仓库 + SSH Key
第 2 天:虚拟环境 + pyproject.toml + .env 环境分离
第 3 天:写好 README + FastAPI 自带文档配置好
第 4 天:日志系统配置(loguru)
第 5 天:pytest 测试 + 覆盖率
第 6 天:pre-commit + Ruff + commitizen
第 7 天:服务器部署:systemd + Nginx + HTTPS
第 8 天:安全加固:UFW + SSH + Fail2Ban
第 9 天:数据库备份 + cron 定时任务
第 10 天:CI/CD (GitHub Actions)
第 11 天:健康检查 + 外部监控
第 12 天:CHANGELOG + 漏洞扫描 + 查漏补缺

参考资源

FastAPI 项目结构与最佳实践: - FastAPI Best Practices (zhanymkanov) -- FastAPI 最佳实践汇总 - Production-Ready FastAPI Project Structure (2026 Guide) -- 生产级项目结构 - FastAPI Best Practices for Production (2026) -- 生产部署最佳实践 - FastAPI Setup Guide for 2025 -- FastAPI 环境搭建

Python 工具链与项目管理: - Python Project Setup 2026: uv + Ruff + Ty + Polars (KDnuggets) -- 2026 年 Python 工具链 - Managing Python Projects With uv (Real Python) -- uv 完整教程 - Python Packaging: pyproject.toml Guide -- 官方 pyproject.toml 指南 - Working on projects with uv -- uv 项目管理文档

部署与运维: - Deploy FastAPI on Ubuntu 24.04 (Gunicorn + Nginx + Certbot) -- Ubuntu 部署全流程 - Deploy FastAPI Like a Pro: GitHub Actions, GitLab CI -- CI/CD + 零停机部署 - Enhancing GitHub Actions CI for FastAPI (PyImageSearch) -- CI 进阶 - FastAPI Deployment Guide (RamNode) -- 服务器部署指南

日志系统: - Choosing a Python Logging Library in 2026 (Dash0) -- Python 日志库选型 - Python Logging with Loguru (Dash0) -- Loguru 生产配置 - Python Logging with Structlog (Dash0) -- Structlog 结构化日志 - Logging in Python: Top 6 Libraries (Better Stack) -- 日志库对比

Git 与分支策略: - Choosing the Right Git Strategy in 2025 -- Git 分支策略对比 - Agile Git Branching Strategies in 2026 (Java Code Geeks) -- 2026 分支策略趋势 - Effortless Code Quality: Pre-Commit Hooks Guide 2025 -- pre-commit 最佳实践

测试: - Testing FastAPI Applications with Pytest -- FastAPI 测试实战 - FastAPI Testing Strategies (greeden.me) -- 测试策略全景

安全: - Linux Server Hardening: SSH + Fail2Ban + UFW -- 服务器安全加固 - Harden Your Linux Server: Fail2Ban and UFW (VPS.DO) -- Fail2Ban 配置 - VPS Security Hardening Checklist 2025 (VPS.DO) -- 安全加固清单 - Hardening SSH 2025 Best Settings -- SSH 加固详解 - pip-audit (PyPI) -- 依赖漏洞扫描