在 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
。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复