Appearance
项目打包与部署到服务器
本节说明如何把本地开发的 Python Web 项目(以 FastAPI + Uvicorn 为例)打成可传输的包,并在 Linux 服务器 上安装依赖、常驻运行,前面用 Nginx 做反向代理。开始前请已了解 虚拟环境的创建 与 requirements.txt 的作用。
部署思路概览
Python Web 项目一般不把本机虚拟环境目录拷到服务器(Windows 与 Linux 二进制不兼容,且体积大)。常见做法是:
- 打包:源码 +
requirements.txt(或pyproject.toml),排除.git、.venv、__pycache__等。 - 上传:
scp、rsync,或由 Jenkins/GitHub Actions 在构建机打包后上传。 - 在服务器上:用与线上一致的 Python 版本新建虚拟环境,
pip install -r requirements.txt,再用 systemd 守护 Uvicorn/Gunicorn,Nginx 对外提供 80/443 并转发到本机端口。
容器化(Docker)也是主流方案,文末略提;先掌握「目录 + venv + 进程管理」更利于理解服务器上实际发生了什么。
上线前检查清单
| 项 | 说明 |
|---|---|
| 依赖锁定 | 使用 requirements.txt,或在 CI 中 pip freeze 生成,避免服务器装到不兼容版本 |
| 配置外置 | 密钥、数据库 URL 等用环境变量或 .env(勿提交 .env,可提交 .env.example) |
| 入口明确 | 例如包名为 app,ASGI 实例为 app,则启动命令为 uvicorn app.main:app |
| Python 版本 | 本地、CI、服务器主版本尽量一致(如均为 3.11) |
生成依赖清单(在已激活且能跑通项目的 venv 中执行):
bash
pip freeze > requirements.txt提交前可人工删去仅开发用的包(如 pytest 若不需要在生产安装可拆成 requirements-dev.txt)。
打包要包含什么、排除什么
应包含:业务代码、requirements.txt(及 pyproject.toml 若使用)、静态资源(若有)、README 或部署说明。
不要包含:.venv / venv、__pycache__、.git、.idea、本地 .env、体积很大的临时文件。
在 Linux / macOS 项目根目录示例(按你实际项目名改压缩包文件名):
bash
tar -czvf myapp.tar.gz \
--exclude='.git' \
--exclude='.venv' \
--exclude='venv' \
--exclude='__pycache__' \
--exclude='*.pyc' \
--exclude='.env' \
.在 Windows 上可:用 WSL 执行同上命令、用 7-Zip 图形界面排除上述目录,或在 CI(Linux 节点) 里打包,避免路径与权限问题。
上传到服务器
假设服务器 user@your-server-ip,上传到 /opt/myapp 的上级目录或用户家目录,再解压:
bash
scp myapp.tar.gz user@your-server-ip:/tmp/
ssh user@your-server-ip
sudo mkdir -p /opt/myapp
sudo tar -xzvf /tmp/myapp.tar.gz -C /opt/myapp
sudo chown -R user:user /opt/myapp目录 /opt/myapp 仅作示例,按运维规范选择即可。
在服务器上安装与试运行
以下以 Ubuntu/Debian 为例,且假设应用入口为 uvicorn app.main:app(即项目内有 app/main.py,其中 app = FastAPI())。
bash
cd /opt/myapp
sudo apt update
sudo apt install -y python3-venv
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
# 先前台试跑,确认无报错再配 systemd
uvicorn app.main:app --host 127.0.0.1 --port 8000浏览器或 curl http://127.0.0.1:8000 访问验证。若应用依赖环境变量,可先 export KEY=value 或下文使用 EnvironmentFile。
使用 systemd 常驻运行
以 Uvicorn 监听本机 8000 为例(生产可提高 worker 数或改用 Gunicorn + Uvicorn Worker,见下节)。
创建服务文件(路径与用户名按实际修改):
ini
# /etc/systemd/system/myapp.service
[Unit]
Description=My FastAPI application
After=network.target
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/myapp
Environment=PATH=/opt/myapp/.venv/bin
# 若有 .env 文件且希望由 systemd 加载(注意权限)
# EnvironmentFile=/opt/myapp/.env
ExecStart=/opt/myapp/.venv/bin/uvicorn app.main:app --host 127.0.0.1 --port 8000
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target启用并启动:
bash
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
sudo systemctl status myapp日志排查:journalctl -u myapp -f。
需要多进程时,可安装 gunicorn 并用 Uvicorn worker(需把 gunicorn 写入 requirements.txt):
bash
/opt/myapp/.venv/bin/gunicorn app.main:app \
-w 4 \
-k uvicorn.workers.UvicornWorker \
-b 127.0.0.1:8000将上述 ExecStart 整行替换进 myapp.service 即可。
Nginx 反向代理(HTTPS 由证书配置)
对外只暴露 Nginx,由它将请求转到本机 Uvicorn:
nginx
server {
listen 80;
server_name api.example.com;
location / {
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;
}
}修改后执行 sudo nginx -t && sudo systemctl reload nginx。HTTPS 可使用 Let’s Encrypt(certbot)等,在 Nginx 中配置 ssl_certificate 等指令。
与 CI/CD 结合
在 Jenkins、GitHub Actions 等流水线中,典型步骤是:检出代码 → 在 Linux 执行 tar 或 docker build → scp/rsync 到服务器 → SSH 执行解压、pip install、systemctl restart myapp。注意构建机上的 工作区路径(如 Git Bash 下的 /c/... 即 Windows 的 C:\...)与 服务器上的 Linux 路径(如 /opt/myapp)不要混用。
容器化(可选)
若团队统一用 Docker:用官方 Python 镜像多阶段构建,镜像内 pip install,入口 CMD 运行 Uvicorn;服务器只跑容器与编排(docker compose / K8s)。优点是环境一致;仍需处理卷、密钥与负载均衡。
小结
- 打包:源码 + 依赖清单,排除 venv、缓存与密钥文件。
- 服务器:新建 venv、
pip install -r requirements.txt,用 systemd 管理进程,Nginx 对外代理。 - 细节:Python 版本一致、依赖可复现、配置走环境变量;Web 路由与目录约定见 Web 开发。