把 Python 应用从开发环境搬到生产服务器上运行,就是部署。从最简单的“把代码扔上去跑”到“用容器标准化一切”,不同的部署方式对应不同的规模和需求。下面介绍三种最主流的做法。
源码部署(直接运行)
最原始也最直接的方式:在目标服务器安装好 Python 解释器后,直接把项目代码拷贝过去,然后用 python app.py 一类的命令启动。
怎么做
- 保证目标机器安装了与开发环境相同版本的 Python(例如 3.12)。
- 将源码整个目录复制到服务器适当位置(如
/opt/myapp)。 - 安装依赖包:
pip install -r requirements.txt(建议先创建虚拟环境,见下一种方式)。 - 启动程序:直接
python main.py或通过nohup、screen后台运行。
优点
- 过程极简,小项目、内部工具、临时脚本用起来很快。
- 不依赖额外软件,只需 Python 和
pip。
缺点
- 环境隔离弱:多个项目共享同一个 Python 解释器和全局 site-packages,依赖版本冲突概率高。
- 部署操作不标准:人工拷贝、手动启动容易出错,回滚困难。
- 启动管理粗糙:进程挂了不会自动重启,通常需要搭配 supervisord 等进程管理工具。
适用场景
- 个人项目、内部测试、一次性运行的数据处理任务。
- 对可靠性要求不高的原型系统。
真实建议:哪怕项目很小,也至少要用到下面的虚拟环境方式,不要直接污染系统 Python。
虚拟环境部署
在源码部署的基础上,增加虚拟环境来隔离依赖,这是中小型 Python 应用最常用的生产部署形式。
怎么做
- 在服务器上创建虚拟环境:
python -m venv /opt/venvs/myapp - 激活环境:
source /opt/venvs/myapp/bin/activate - 在激活的环境中安装依赖:
pip install -r requirements.txt - 将源码放在项目目录(如
/opt/myapp),通过 WSGI/ASGI 服务器(如 Gunicorn、Uvicorn)配合进程管理器启动。
常见启动命令示例(Gunicorn + Flask)
/opt/venvs/myapp/bin/gunicorn -w 4 -b 0.0.0.0:8000 app:app
- 这里直接使用虚拟环境内的
gunicorn,不需要先activate,保证启动路径明确。
常用进程管理工具
- systemd(推荐):Linux 系统自带,配置一个
.service文件就能实现自动重启、开机自启、日志收集。 - supervisord:轻量进程管理,适合非 systemd 环境。
优点
- 每个项目拥有独立的 Python 环境和依赖库,版本互不干扰。
- 配合 systemd 可实现进程守护、自动重启,可靠性大幅提升。
- 部署脚本化容易,可以将虚拟环境创建、依赖安装、代码更新写成脚本,实现半自动化。
缺点
- 仍然依赖宿主机的 Python 版本和操作系统库(如编译 OpenSSL 等的系统包),不同服务器环境差异可能导致问题。
- 多台服务器部署时,需要复制相同的环境搭建步骤,手动运维工作量随机器数量线性增加。
适用场景
- 中小型 Web 应用、API 服务,服务器数量不多(1~5 台)时非常方便。
- 运维资源有限的小团队,能用脚本+systemd 就搞定大部分部署需求。
Docker 容器化部署
当应用需要频繁扩展、环境完全一致化,或团队已经采用微服务架构时,Docker 部署是当前业界主流。
怎么做
- 编写 Dockerfile,描述如何构建镜像(示例):
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
- 构建镜像:
docker build -t myapp:latest . - 运行容器:
docker run -d -p 8000:8000 --name myapp myapp:latest - 配合容器编排:生产环境中常用 Docker Compose(单机多容器)或 Kubernetes(集群管理)来管理服务。
优点
- 环境一致性:镜像包含应用代码、依赖、运行时、系统库,彻底消除“我机器上跑得好好的”问题。
- 快速扩缩容:镜像启动就是完整的服务,便于水平扩展和滚动更新。
- 生态集成:与其他基础设施(如 Nginx、Redis、数据库)打包成一整套编排配置,便于迁移和部署。
- CI/CD 友好:可以利用镜像版本标签实现回滚,部署改为拉取新镜像即可。
缺点
- 学习曲线:团队需要掌握 Dockerfile 编写、镜像优化、网络与存储配置。
- 资源开销:容器比直接进程稍重,但相对于带来的好处,这点开销通常值得。
- 日志和调试习惯需要调整:容器是无状态的,日志应输出到标准输出,然后由 Docker 或日志平台收集。
适用场景
- 多服务、多环境的微服务架构。
- 需要频繁交付、弹性伸缩的生产级应用。
- 团队已具备一定的容器化运维能力,或准备走向 Kubernetes。
真实建议:即使一开始只用虚拟环境部署,也建议早早为项目补充 Dockerfile。它既是环境说明文档,也为将来上容器化铺平了路。
三种方式的选择可以这样看:
- 只有一两台机器,对可靠性要求不高 → 虚拟环境部署足够。
- 需要多机部署、CI/CD 自动化、环境严格一致 → 直接上 Docker 容器化。
- 源码部署仅用于临时测试,生产不建议裸奔。
无论采用哪种方式,都要记住两个核心:环境可复现(别人拿到你的配置能搭出一模一样的运行环境)和故障可自愈(进程挂了能自动拉起)。这才是生产部署的真正目标。