• 阿里云ECS部署python及flask(一)
  • 阿里云ECS部署python及flask(二)使用uwsgi emperor +Nginx部署自动启动多个web项目
  • 阿里云ECS部署python及flask(三)通过设置uid和gid来改变uwsgi+emperor通常使用root权限的问题

之前配置uwsgi+emperor时,并没有使用uid和gid,直接用root用户。所以在log中总是出现:

WARNING: you are running uWSGI as root !!! (use the --uid flag)

uwsgi-docs中的介绍:https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/Emperor.html 摘抄片断:

Tyrant模式 (安全的多用户托管)

emperor通常以root运行,在每个实例的配置中设置UID和GID。然后,vassal实例在处理请求之前删除特权。在这个模式下,如果你的用户可以访问自己的uWSGI配置文件,那么你不能信任他们会设置正确的 uid 和 gid 。你可以以非特权用户运行emperor (使用 uid 和 gid),但是所有的vassal之后将会运行在相同的用户之下,因因为非特权用户不能自己切换成其他用户。对于这种情况,可以使用Tyrant模式 —— 仅需添加 emperor-tyrant 选项。

在Tyrant模式下,Emperor会使用vassal配置文件(或者对于其他Imperial监控器,通过一些配置的其他方法)的UID/GID来运行vassal。如果使用了Tyrant模式,那么vassal配置文件必须是UID/GID > 0。如果UID或者GID为0,或者一个已经在运行的vassal的配置的UID或GID发生了变化,那么将会出现一个错误。

经过一翻研究,通过新创建一个用户组和用户名(我这里使用组名uwsgigroup和用户名uwsgi),并修改一些目录的所属用户和用户组就可以解决。过程如下:

1、 创建新用户组:(组名:uwsgigroup,gid:1001)

groupadd -g 1001 uwsgigroup

2、创建新用户:(用户名:uwsgi,uid:1001,加入到uwsgi组)

useradd -u 1001 -g uwsgigroup uwsgi

3、创建一个新的项目目录,将项目文件都拷到其中。并修改其所属用户及用户组:

sudo mkdir /uwsgi
cp -rf /root/myproject /uwsgi
chown -R uwsgi:uwsgigroup /uwsgi

4、修改/etc/uwsgi/emperor.ini(即添加uid和gid):

[uwsgi]
emperor = /etc/uwsgi/vassals
# 添加下面两句
uid = 1001
gid = 1001

5、修改/etc/uwsgi/vassals/myproject.ini(因为项目目录已经改变,所以需要修改以前ini文件中的chdir):

[uwsgi]
# uwsgi 启动时所使用的地址与端口
socket = 127.0.0.1:8000

# 外网访问端口,如果直接用uWSGI外网,这里由于使用了Nginx,故注释掉
# http= :80

# 指向网站目录
chdir = /uwsgi/myproject/psss

# python 启动程序文件
wsgi-file = psss.py

# python 程序内用以启动的 application 变量名
# app 是 manage.py 程序文件内的一个变量,这个变量的类型是 Flask的 application 类
callable = app

# 处理器数
processes = 4

# 线程数
threads = 2

#状态检测地址
stats = 127.0.0.1:9191

#daemonize=/var/log/uwsgi.log
#stats=%(chdir)/uwsgi/uwsgi.status
#pidfile=%(chdir)/uwsgi/uwsgi.pid

home=%(chdir)/venv
stats=%(chdir)/uwsgi/uwsgi.status
pidfile=%(chdir)/uwsgi/uwsgi.pid

master=true
vaccum=true
touch-reload=%(chdir)

# 设置log文件
# 单独开一个线程进行 log 写入工作,这样有更好的性能
threaded-log = true
#daemonize=/var/log/uwsgi.log
req-logger=file:/var/log/uwsgi/req.log
logger=file:/var/log/uwsgi/logger.log

6、修改/var/log/uwsgi的所属用户和用户组

chown -R uwsgi:uwsgigroup /var/log/uwsgi

7、由于修改了项目目录,所以nginx.conf中的static项也需要做相应修改。并且将user也改为uwsgi。(参考文章:https://www.v2ex.com/t/385529。)

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user uwsgi;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       4000 default_server;
        # listen       [::]:80 default_server;
        server_name  _;
        # root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        	uwsgi_pass 127.0.0.1:8000;
          include uwsgi_params;
        }
	   location /static {
    	     alias /uwsgi/myproject/psss/app_1/static;
        }
        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

8、重启服务:

systemctl restart emperor.uwsgi.service
 systemctl restart nginx.service