Ubuntu 上怎么部署 Python 项目:从环境准备到 Gunicorn、Nginx 与 systemd

Noah
Noah
发布时间:2026-08-23 | 30人浏览过
原创

前言

把 Python 项目部署到 Ubuntu,难点通常不在“能不能跑起来”,而在于怎么把环境、依赖、进程和对外访问一层层接稳。这篇文章按实际上线顺序整理了完整流程,并保留原始命令与配置示例,方便你判断自己当前卡在基础环境、应用启动、反向代理还是开机自启这一环。

把 Python 项目放到 Ubuntu 服务器上,真正影响上线是否顺利的,通常不是某一条命令,而是环境、依赖、进程管理和反向代理有没有按顺序接好。下面这篇按生产部署链路重排了一遍:先确认服务器基础环境,再把项目跑起来,最后补齐 Nginx 与 systemd,让服务能稳定对外提供访问。

如果你正在部署 Flask、Django 或 FastAPI 一类 Web 项目,这套流程都能直接参考。文中保留了原始命令、配置文件和版本要求,同时会说明每一步在生产环境里到底解决什么问题,方便你判断自己的部署卡在哪一层。

准备 Ubuntu 基础环境

服务器到手后,先确认 Python、pip 和虚拟环境工具是否齐全。Ubuntu 通常自带 Python 3,但生产环境里最好仍然手动安装一次,避免后面缺少 pip 或 venv。

sudo apt update
sudo apt install python3 python3-pip python3-venv -y

安装完成后,先检查版本是否满足要求。原文建议 Python 至少为 3.8,且 pip3 可以正常调用:

python3 --version
pip3 --version

这一步的目的很直接:后续无论是建虚拟环境、装依赖还是跑 Gunicorn,都依赖这里的基础环境正常可用。

把项目代码上传到服务器

部署前需要先把项目文件放到服务器。常见做法有两种:一种是用 Git 直接拉取代码,另一种是用 scp 从本地复制整个项目目录。这里沿用原文示例,用 scp 上传:

scp -r /local/project/path username@server_ip:/remote/deploy/path

上传完成后,进入项目目录确认关键文件是否齐全,尤其是 requirements.txt。这个文件决定了服务器会安装哪些 Python 依赖,也是本地环境与线上环境保持一致的基础。

创建虚拟环境并安装依赖

Python 项目不建议直接把依赖装进系统全局环境。更稳妥的做法是在项目根目录创建一个独立虚拟环境,把当前项目需要的包都隔离进去。

创建并激活虚拟环境

python3 -m venv myenv
source myenv/bin/activate

激活后,终端提示符通常会变成 (myenv) user@server。这意味着后面的 pip install、gunicorn 等操作都会发生在这个虚拟环境里,而不会污染系统全局 Python。

安装项目依赖

依赖安装前可以先升级一次 pip,减少因为工具版本过旧导致的兼容性问题:

Python 项目在 Ubuntu 上的部署链路图,展示代码上传、虚拟环境、Gunicorn、Nginx 与外部访问之间的关系
Ubuntu 部署链路与流量转发关系用一张结构图把“项目进程如何对外提供访问”说明白,方便读者理解 Gunicorn 和。
pip install --upgrade pip
pip install -r requirements.txt

如果这里就报错,通常问题会集中在三类:依赖版本冲突、系统缺少编译或运行库、以及 requirements.txt 本身不完整。建议优先在这一层把问题清掉,再继续后面的服务化部署。

先跑通应用,再切到 Gunicorn

项目上传和依赖安装完成后,先确认应用本身能启动。开发阶段可以直接运行入口文件做一次基础测试:

python app.py

但这只适合开发调试,不适合生产环境。以 Flask 为例,自带开发服务器在并发、稳定性和进程管理上都不适合直接对外提供服务。

为什么生产环境要用 Gunicorn

更常见的做法是用 Gunicorn 作为 WSGI 服务器来承接应用进程:

pip install gunicorn
gunicorn -w 4 -b 127.0.0.1:8000 app:app

注意:app:app 表示 app.py 文件中的 Flask 应用实例对象。前一个 app 是模块名,后一个 app 是应用对象名。

这里的 -w 4 表示启动 4 个 worker,-b 127.0.0.1:8000 表示只监听本机 8000 端口。这样外部流量不会直接打到应用进程,而是交给前面的 Nginx 统一处理。

用 Nginx 对外接流量与静态文件

到了生产环境,Nginx 基本是必备组件。它负责处理客户端请求、转发动态流量、直接提供静态文件,还可以继续承担负载均衡和 SSL 终止等工作。

安装 Nginx

sudo apt install nginx -y

创建站点配置

原文给出的配置文件路径是 /etc/nginx/sites-a vailable/myapp。实际使用时通常应为 /etc/nginx/sites-available/myapp,这里保留原命令结构,部署时请按系统实际路径填写:

sudo nano /etc/nginx/sites-a vailable/myapp

写入如下配置,并将 your_domain_or_ip、静态目录路径和端口改成自己的实际值:

server {
    listen 80;
    server_name your_domain_or_ip;

    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;
    }

    location /static/ {
        alias /remote/deploy/path/static/;
    }
}

启用配置并检查语法

sudo ln -s /etc/nginx/sites-a vailable/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

其中 sudo nginx -t 很关键,它能在重载前先检查配置语法。如果这一条没通过,优先检查配置文件路径、花括号配对、alias 目录是否存在,以及代理端口是否和 Gunicorn 启动端口一致。

配置 systemd,让服务开机自启

手动运行 Gunicorn 只能解决“现在能跑”,不能解决“服务器重启后还能自动恢复”。要把应用真正变成系统服务,就需要交给 systemd 管理。

systemd 托管 Gunicorn 服务的配置重点图,展示服务文件中的关键字段与启动后的检查项
systemd 服务文件关键项与检查点systemd 是生产环境稳定运行的关键一环,这张图集中说明服务文件里最容易写错的字段。

创建服务文件

创建 /etc/systemd/system/myapp.service:

sudo nano /etc/systemd/system/myapp.service

写入以下内容,注意替换用户名、工作目录、虚拟环境路径和应用入口:

[Unit]
Description=Gunicorn Server for My Python App
After=network.target

[Service]
User=your_username
Group=www-data
WorkingDirectory=/remote/deploy/path
Environment="PATH=/remote/deploy/path/myenv/bin"
ExecStart=/remote/deploy/path/myenv/bin/gunicorn --workers 4 --bind unix:/run/myapp.sock app:app
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

加载并启动服务

sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl enable myapp
sudo systemctl status myapp

当状态显示 active (running) 时,说明服务已经正常启动。这里还要特别注意一个细节:上面的 ExecStart 绑定的是 unix:/run/myapp.sock,而前面 Nginx 示例使用的是 http://127.0.0.1:8000。实际部署时,这两边必须统一,要么都走 TCP 端口,要么都走 Unix Socket,否则 Nginx 无法连到 Gunicorn。

可选方案:用 Docker 保持环境一致

如果项目依赖复杂,或者你希望把运行环境彻底打包固定,Docker 也是常见选择。原文给出的示例镜像基于 python:3.9-slim:

FROM python:3.9-slim
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 8000
CMD ["gunicorn", "--workers", "4", "--bind", "0.0.0.0:8000", "app:app"]

构建镜像并运行容器:

docker build -t my-python-app .
docker run -d -p 8000:8000 --name myapp my-python-app

这种方式的好处是本地、测试和生产可以尽量保持同一套运行环境。容器启动后,Nginx 仍然可以继续作为前端代理,把请求转发到 localhost:8000。

上线前后要检查的几个关键点

  • 权限问题:不要直接用 root 跑应用,优先使用普通用户,并按需加入 www-data 组。
  • 端口开放:如果是云服务器,记得在安全组中开放 80(HTTP)和 443(HTTPS)端口。
  • 静态文件处理:Django 或 Flask 的静态资源更适合交给 Nginx 通过 location /static/ 直接处理,避免占用应用进程。
  • HTTPS:建议使用 Let's Encrypt 的 certbot 为站点申请免费证书,尽快切到 HTTPS。

整体来看,Ubuntu 上部署 Python 项目的核心思路并不复杂:代码和依赖先在服务器上跑通,再用 Gunicorn 承接应用进程,用 Nginx 对外暴露访问,最后交给 systemd 做长期托管。不同框架在入口命令上会有差别,但部署链路基本一致。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表