在 CentOS 7 上部署一个 Flask 应用是一个将开发项目转化为可供公网访问的服务的关键步骤,与开发环境不同,生产环境需要一个稳定、高效且安全的架构,本文将详细介绍如何在 CentOS 7 服务器上,通过结合使用 Gunicorn 作为 WSGI 服务器和 Nginx 作为反向代理,来部署一个标准的 Flask 应用,这种架构能够充分发挥 Nginx 处理高并发连接和静态文件的优势,同时让 Gunicorn 专注于运行 Python 应用,是业界广泛采用的最佳实践。

环境准备
在开始部署之前,请确保您拥有一台安装了 CentOS 7 的服务器,并拥有 root 权限或 sudo 权限,建议为服务器配置一个静态 IP 地址和一个域名(如果需要通过域名访问)。
我们将安装以下核心软件组件,它们各自扮演着不可或缺的角色:
| 软件名称 | 角色定位 | 功能说明 |
|---|---|---|
| Python 3 | 应用运行环境 | Flask 应用基于 Python 3 运行 |
| Gunicorn | WSGI 服务器 | 连接 Python Web 应用与 Web 服务器,管理应用进程 |
| Nginx | 反向代理/Web 服务器 | 处理 HTTP 请求、负载均衡、提供静态文件服务 |
| FirewallD | 防火墙 | 控制服务器端口访问,保障安全 |
安装必要的软件
更新系统软件包到最新版本,确保所有依赖都是最新的。
sudo yum update -y
CentOS 7 的默认源中不包含 Nginx 和 Python 3,因此需要先安装 EPEL (Extra Packages for Enterprise Linux) 仓库。
sudo yum install epel-release -y
安装 Nginx、Python 3 以及相关的开发工具和包管理器。
sudo yum install nginx python3 python3-pip python3-devel -y
为了方便管理代码,建议同时安装 Git。
sudo yum install git -y
创建并配置 Flask 应用
为了演示,我们将在 /var/www/ 目录下创建一个简单的 Flask 应用。
-
创建项目目录
sudo mkdir /var/www/myflaskapp
-
创建 Flask 应用文件
使用
vi或nano编辑器创建一个名为app.py的文件。sudo vi /var/www/myflaskapp/app.py
在文件中输入以下简单的 Flask 应用代码:
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return "<h1>Hello, Flask on CentOS 7!</h1>" if __name__ == '__main__': app.run() -
创建依赖文件
在同一目录下创建
requirements.txt文件,列出项目的所有依赖,目前我们只有 Flask。sudo vi /var/www/myflaskapp/requirements.txt
Flask gunicorn -
设置目录权限

为了避免权限问题,将项目目录的所有权授予当前登录的用户(假设为
centos,请替换为您的用户名)。sudo chown -R centos:centos /var/www/myflaskapp
配置 Gunicorn
Gunicorn 是一个高性能的 Python WSGI HTTP 服务器,我们将用它来运行我们的 Flask 应用。
-
创建并激活 Python 虚拟环境
进入项目目录,创建一个独立的虚拟环境,以隔离项目依赖。
cd /var/www/myflaskapp python3 -m venv venv source venv/bin/activate
-
安装依赖
在激活的虚拟环境中,使用 pip 安装
requirements.txt中定义的依赖。pip install -r requirements.txt
-
创建 Gunicorn Systemd 服务文件
为了让 Gunicorn 作为系统服务在后台运行,并实现开机自启,我们需要创建一个 systemd 服务文件。
sudo vi /etc/systemd/system/gunicorn.service
在文件中填入以下内容,请确保
User、Group和WorkingDirectory与您的实际配置匹配。[Unit] Description=gunicorn daemon for myflaskapp After=network.target [Service] User=centos Group=centos WorkingDirectory=/var/www/myflaskapp ExecStart=/var/www/myflaskapp/venv/bin/gunicorn --workers 3 --bind unix:myflaskapp.sock -m 007 app:app [Install] WantedBy=multi-user.target
配置说明:
--workers 3: 启动 3 个工作进程,通常设置为 CPU 核心数 * 2 + 1。--bind unix:myflaskapp.sock: 通过 Unix socket 文件与 Nginx 通信,比 TCP 端口效率更高。-m 007: 设置 socket 文件的权限。app:app: 指的是app.py文件中的app实例。
-
启动并启用 Gunicorn 服务
sudo systemctl start gunicorn sudo systemctl enable gunicorn
可以使用
sudo systemctl status gunicorn检查服务是否正常运行。
配置 Nginx 作为反向代理
我们需要配置 Nginx,让它接收来自互联网的 HTTP 请求,并将其转发给 Gunicorn 处理。
-
创建 Nginx 配置文件

在
/etc/nginx/conf.d/目录下为我们的应用创建一个新的配置文件。sudo vi /etc/nginx/conf.d/myflaskapp.conf
填入以下配置:
server { listen 80; server_name your_server_ip_or_domain; location / { include proxy_params; proxy_pass http://unix:/var/www/myflaskapp/myflaskapp.sock; } }配置说明:
listen 80;: 监听 80 端口(HTTP)。server_name: 替换为您的服务器 IP 地址或域名。proxy_pass: 将请求转发到 Gunicorn 创建的 Unix socket 文件。
-
测试并重启 Nginx
在应用新配置前,先检查 Nginx 配置文件语法是否正确。
sudo nginx -t
如果显示
syntax is ok和test is successful,则可以重启 Nginx 服务。sudo systemctl restart nginx
配置防火墙
我们需要开放 HTTP 和 HTTPS 端口,允许外部流量访问 Nginx。
sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload
至此,整个部署流程已经完成,您可以在浏览器中访问您服务器的 IP 地址或域名,应该能看到 "Hello, Flask on CentOS 7!" 的字样。
相关问答FAQs
问题 1:为什么不能直接使用 Flask 自带的服务器进行生产部署?
解答:Flask 自带的服务器(通过 app.run() 启动)是一个开发服务器,其设计目的是为了方便开发和调试,它存在几个关键问题使其不适合生产环境:它是单线程的,无法处理并发请求,性能极差;它缺乏必要的安全机制和错误处理,非常不稳定,任何一个未捕获的异常都可能导致整个服务崩溃,而像 Gunicorn 这样的生产级 WSGI 服务器,能够管理多个工作进程来处理并发请求,具备进程监控和自动重启功能,更加稳定、安全和高效,是生产环境的标准选择。
问题 2:部署后访问网站出现 502 Bad Gateway 错误,应该如何排查?
解答:502 Bad Gateway 错误通常意味着 Nginx 作为网关无法从上游服务(这里是 Gunicorn)获得有效的响应,排查步骤如下:
- 检查 Gunicorn 服务状态:运行
sudo systemctl status gunicorn,查看服务是否正在运行(active (running)),如果未运行,查看日志journalctl -u gunicorn找出失败原因,很可能是代码错误或权限问题。 - 检查 Socket 文件:确认 Nginx 配置中
proxy_pass指向的 socket 文件路径(/var/www/myflaskapp/myflaskapp.sock)与 Gunicorn 配置中--bind的路径完全一致,并且该文件确实存在。 - 检查 Nginx 错误日志:查看 Nginx 的错误日志(通常位于
/var/log/nginx/error.log),日志中通常会包含更详细的错误信息,如 "permission denied while connecting to upstream"。 - 检查 SELinux:CentOS 7 默认开启 SELinux,它可能会阻止 Nginx 访问 socket 文件,可以临时关闭 SELinux(
sudo setenforce 0)测试是否能解决问题,如果可以,则需要设置正确的 SELinux 策略,例如运行sudo setsebool -P httpd_can_network_connect 1。