Skip to content

项目打包与部署到服务器

本节说明如何把本地开发的 Python Web 项目(以 FastAPI + Uvicorn 为例)打成可传输的包,并在 Linux 服务器 上安装依赖、常驻运行,前面用 Nginx 做反向代理。开始前请已了解 虚拟环境的创建requirements.txt 的作用。

部署思路概览

Python Web 项目一般不把本机虚拟环境目录拷到服务器(Windows 与 Linux 二进制不兼容,且体积大)。常见做法是:

  1. 打包:源码 + requirements.txt(或 pyproject.toml),排除 .git.venv__pycache__ 等。
  2. 上传scprsync,或由 Jenkins/GitHub Actions 在构建机打包后上传。
  3. 在服务器上:用与线上一致的 Python 版本新建虚拟环境,pip install -r requirements.txt,再用 systemd 守护 Uvicorn/GunicornNginx 对外提供 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 Encryptcertbot)等,在 Nginx 中配置 ssl_certificate 等指令。

与 CI/CD 结合

Jenkins、GitHub Actions 等流水线中,典型步骤是:检出代码 → 在 Linux 执行 tardocker buildscp/rsync 到服务器 → SSH 执行解压、pip installsystemctl 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 开发