官方推荐在 systemd 中使用 emperor 的方式进行服务器自启动的部署。我觉得在 uwsgi 进程之上再加一个管理进程,显得有点重。于是就没用 emperor 的方式而是直接调用业务的 uwsgi 进行部署。

uwsgi.ini 内容如下

[uwsgi]
chdir=/path/of/project
module=project.wsgi:application
master=True
pidfile=/run/uwsgi.pid
vacuum=True
max-requests=5000
socket=/run/uwsgi.socket
thunder-lock=True
enable-threads=True

这里面有两个坑:

  1. pidfile 不要按照教程推荐的,将 unix socket 文件放到 /tmp 下。原因是 systemd 会建立各服务私有的临时目录。导致 nginx 可能会找不到 uwsgi 的临时目录。
  2. 与 emperor 相同,不要使用 daemonize 方式启动 uwsgi 进程。

/usr/lib/systemd/system/uwsgi.service 内容如下

[Unit]
Description=uWSGI Server
After=syslog.target

[Service]
ExecStart=/usr/bin/scl enable python33 'uwsgi --ini /path/to/uwsgi.ini'
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target

使该服务自启动的命令行是 systemctl enable uwsgi.service

这里面稍微注意一下使用 scl 的方式调用 Python 3.3 就好了,别忘了引号,引号也不用转义。

nginx.conf 的相关内容如下

 location / {
     include /etc/nginx/uwsgi_params;
     uwsgi_pass unix:/run/uwsgi.socket;
 }

其中,将 unix socket 放到非 /tmp 目录的原因之前已经阐述过。另外一个坑是注意在 nginx 中声明 unix socket 的语法。