最近,搞了一台 Debian 12 机器,打算部署一个使用 Flask 框架的小应用。按之前的套路安装 Python3、uWSGI 以及 Nginx 遇到各种不顺,后来发现自己走了很多弯路,简单的事情复杂化了。

Debian 12 预装了 Python3,版本是 3.11.2,如果应用不要求最新版的 Python,那么都能满足要求。只是预装的版本只有解释器,其它的模块需要自行安装。

Python 应用最重要的一点是配置一个配对独立的虚拟运行环境,这样各个应用就不会相互影响。首先使用如下命令,添加 Python3 虚拟环境模块,并设置虚拟环境 venv:

# apt install python3.11-venv
# mkdir -p /App/venv
# python3 -m venv /App/venv

此时,就会在”/App/venv”目录下创建一个Python3 的虚拟环境。之后,就可以使用如下命令进入虚拟环境,使用”pip”命令安装 Python 应用所需要的模块了:

# source /App/venv/bin/activate
(venv)# pip install flask

全部所需要的模块都安装完成后,理论上这个 Python3 应用就可以正常访问了。但是正式环境一般不直接使用应用框架内置的 Web 服务器,因为其并发处理存在性能问题。一般都会使用uWSGI。

uWSGI 是一个 Web 服务器,它实现了 WSGI 协议、uwsgi、http 等协议。WSGI 是一种 Web 服务器网关接口。它是一个 Web 服务器(如nginx,uWSGI等服务器)与 web 应用(如用 Flask 框架写的程序)通信的一种规范。使用 uWSGI 的目的,就是通过它来完成 web 应用同 Nginx 之间的桥梁作用,正确而高效展示动态网页内容。

Python 3 通过 pip 命令安装 uWSGI 时,往往会因为高版本的兼容性问题不能正确生成可执行文件。事实上我们没有必要自己通过 Python 来生成可执行文件,直接使用 Debain 软件库中的 uWSGI 即可。只需要给这个 uWSGI 安装 Python3 插件,同样可以完成相应工作。

# apt install uwsgi
# apt install uwsgi-plugin-python3

之后,就可以配置 uWSGI 启动 Python3 的 web 应用了。假设 web 应用的目录为”/App/webapp”,在”/App”目录下创建一个 uWSGI 的配置文件”uwsgi.ini”,内容如下:

[uwsgi]
chdir=/App/webapp/
home=/App/venv
module=webapp
callable=app
master=true
processes=2
socket=/App/uwsgi/webapp.sock
status=/App/uwsgi/uwsgi.status
pidfile=/App/uwsgi/uwsgi.pid
logto=/App/uwsgi/uwsgi.log
chmod-socket=666
logfile-chmod=644
# daemonize=/App/uwsgi/uwsgi.log
uid=nginx
gid=nginx
procname-prefix-spaced=webApp
plugins = python3

配置项的说明如下:

  • chdir:是项目的工作目录,也就是包含启动 web 应用的那个 Python 文件所在的目录
  • home:是 Python 解释器所在目录,不必指定”bin”目录
  • moudle:是启动 web 应用的那个 Python 文件的文件名,示例为 webapp.py,所以使用wepapp
  • callable:是使用框架时指定给 web 框架对象的名称,一般使用 app
  • master:指是否使用主进程
  • processes:指定工作进程的数量,根据需要设置,示例设置为2
  • socket:设置 uWSGI 与 Nginx 的通信方式使用 socket 文件,并指定该文件的位置
  • status:设置 uWSGI 状态文件的位置
  • pidfile:设置 uWSI 主进程文件的位置
  • logto:设置 uWSI 日志文件的位置
  • chmod-socket:设置 socket 文件的权限
  • logfile-chmod:设置日志文件的权限
  • uid:指定 uWSGI 的启动用户
  • gid:指定 uWSGI 的启动用户的属组
  • procname-prefix-spaced:设置 uWSGI 进程的前缀名,用于快速查找 web 应用进程
  • plugins:指示uWSGI 使用 Python3 插件启动 web 应用
  • #daemonize=/App/uwsgi/uwsgi.log:同样是设置 uWSGI 日志文件的位置,并指示 uWSGI 以守护进程方式工作,与 logto 是互斥项,由于之后要设置 uWSGI 为系统服务,与守护进程工作模式冲突,所以采用了示例的方式,如果不需要设置系统服务,可以使用该设置

当然,uWSGI 还有更多设置项,可能参考其 >>官方网站<< 了解相关内容。

全部完成后,可以使用下命令尝试启动 web 应用:

# uwsgi --ini /App/uwsgi.ini
# ps -ef | grep webApp

如果启动正常,也可以查找到相应的进程,则说明 uWSGI 配置正确,web 应用可以与 Nginx 通信了。之后就需要配置 Nginx 连接 uWSGI,以使 web 应用可以在浏览器中正确显示。

为 Nginx 配置一个新的 sever 配置块,内容如下:

server {
    listen       80;
    server_name  localhost;

    location / {
        try_files $uri @app;
    }
    
    location @app {
        include uwsgi_params;
        uwsgi_pass unix:/App/uwsgi/webapp.sock;
    }

    # deny running scripts inside writable directories
    location ~* /(images|cache|media|logs|tmp)/.*\.(php|pl|py|jsp|asp|sh|cgi)$ {
            return 403;
            error_page 403 /403_error.html;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /App/webapp/html;
    }
}

配置中最主要的内容是”uwsgi_pass unix:/App/uwsgi/webapp.sock;”,意思是调用 Nginx 的 uwsgi_pass 模块,来访问由 uWSGI 生成的网页页面内容,生成静态 HTML 页面。

全部配置正确后,就可以启动 nginx,然后通过浏览器来访问 web 应用了。

使用命令行来启动停止 uWSGI 非常不方便,Debian 12 系统可以通过 systemd 来管理它。在”/lib/systemd/system”目录创建一个”webApp.service”的文件(注意最好不要用uwsgi.service,以免服务启动异常),内容如下:

[Unit]
Description=My Web Application
After=syslog.target network.target

[Service]
Type=simple
User=root
Group=root
ExecStart=/usr/bin/uwsgi --ini /App/uwsgi.ini
ExecReload=/bin/kill -HUP $MAINPID
KillSignal=SIGQUIT
PrivateTmp=true
Restart=always

[Install]
WantedBy=multi-user.target

文件添加完成后,就可以使用如下命令启动 uWSGI 并查看状态了:

# systemctl start webApp
# systemctl status webApp

图.1 查看 uWSGI 服务状态

如图所示,uWSGI 已经成为系统服务并正常运行了。

以上就是 Debian 12系统配置uWSGI+Nginx运行环境的全部内容,希望有所帮助。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注