uWSGI with cookiecutter Pyramid 应用第1部分:基本UWSgi+nginx

uWSGI is a software application for building hosting services. It is named after the Web Server Gateway Interface (the WSGI 许多python web框架所遵循的规范)。

This guide will outline broad steps that can be used to get a cookiecutter Pyramid application running under uWSGI 和NGIX。这个特定的教程是在Ubuntu18.04上开发和测试的,但是对于所有系统来说,指令应该基本相同,在那里您可以调整命令和文件的特定路径信息。

备注

对于那些一心想在UWSGI下运行Pyramid应用程序的人来说,这是你的指南。

但是,如果您只是在寻找一个性能良好的、具有自动启动功能的生产级服务器,那么waitress+systemd的学习曲线要温和得多。

这么说,我们开始吧。

  1. Install prerequisites.

    $ sudo apt install -y uwsgi-core uwsgi-plugin-python3 python3-cookiecutter \
                          python3-pip python3-venv nginx
    
  2. 创建一个 Pyramid 应用。对于本教程,我们将使用 starter cookiecutter . 见 Creating a Pyramid Project 有关创建新项目的详细信息。

    $ cd ~
    $ python3 -m cookiecutter gh:Pylons/pyramid-cookiecutter-starter
    

    If prompted for the first item, accept the default yes 按回车键。

    1You've cloned ~/.cookiecutters/pyramid-cookiecutter-starter before.
    2Is it okay to delete and re-clone it? [yes]: yes
    3project_name [Pyramid Scaffold]: myproject
    4repo_name [myproject]: myproject
    5Select template_language:
    61 - jinja2
    72 - chameleon
    83 - mako
    9Choose from 1, 2, 3 [1]: 1
    
  3. 创建一个 virtual environment 我们将使用它来安装我们的应用程序。

    $ cd myproject
    $ python3 -m venv env
    
  4. 安装你的 Pyramid application and its dependencies.

    $ env/bin/pip install -e ".[testing]"
    
  5. Create a new directory at ~/myproject/tmp two users have access to change into the ~/myproject/tmp directory: your current user (mine is ubuntu ), and the user that nginx will run as (often named www-datanginx

  6. 添加 [uwsgi] 截面至 production.ini . Here are the lines to include:

     1[uwsgi]
     2proj = myproject
     3chdir = /home/ubuntu/%(proj)
     4processes = 2
     5threads = 2
     6offload-threads = 2
     7stats =  127.0.0.1:9191
     8max-requests = 5000
     9master = True
    10vacuum = True
    11enable-threads = true
    12harakiri = 60
    13chmod-socket = 020
    14plugin = python3
    15pidfile=%(chdir)/tmp/%(proj).pid
    16socket = %(chdir)/tmp/%(proj).sock
    17virtualenv = %(chdir)/env
    18uid = ubuntu
    19gid = www-data
    20# Uncomment `wsgi-file`, `callable`, and `logto` during Part 2 of this tutorial
    21#wsgi-file = wsgi.py
    22#callable = app
    23#logto = /var/log/uwsgi/%(proj).log
    

    And here is an explanation of the salient options:

     1# Explanation of Options
     2#
     3# proj = myproject                    # Set a variable named "proj"
     4#                                       so we can use it elsewhere in this
     5#                                       block of config.
     6#
     7# chmod-socket = 020                  # Change permissions on socket to
     8#                                       at least 020 so that, in combination
     9#                                       with "--gid www-data", nginx will be able
    10#                                       to write to it after uWSGI creates it.
    11#
    12# enable-threads                      # Execute threads that are in your app
    13#
    14# plugin = python3                    # Use the python3 plugin
    15#
    16# socket = %(chdir)/tmp/%(proj).sock  # Where to put the unix socket
    17# pidfile=%(chdir)/tmp/%(proj).pid    # Where to put PID file
    18#
    19# uid = ubuntu                        # Masquerade as the ubuntu user.
    20#                                       This grants you permissions to use
    21#                                       python packages installed in your
    22#                                       home directory.
    23#
    24# gid = www-data                      # Masquerade as the www-data group.
    25#                                       This makes it easy to allow nginx
    26#                                       (which runs as the www-data group)
    27#                                       access to the socket file.
    28#
    29# virtualenv = (chdir)/env            # Use packages installed in your
    30#                                       virtual environment.
    
  7. Invoke uWSGI with --ini-paste-logged .

    There are multiple ways to invoke uWSGI. 使用 --ini-paste-logged 是最简单的,因为它不需要显式的入口点。

     1$ cd ~/myproject
     2$ sudo uwsgi --plugin python3 --ini-paste-logged production.ini
     3
     4# Explanation of Options
     5#
     6# sudo uwsgi                          # Invoke as sudo so you can masquerade
     7#                                       as the users specfied by ``uid`` and
     8#                                       ``gid``
     9#
    10# --plugin=python3                    # Use the python3 plugin
    11#
    12# --ini-paste-logged                  # Implicitly defines a wsgi entry point
    13#                                       so that you don't have to.
    14#                                       Also enables logging.
    
  8. 验证上一步的输出是否包含一行,其外观大致如下:

    WSGI app 0 (mountpoint='/') ready in 1 seconds on interpreter 0x5615894a69a0 pid: 8827 (default app)
    

    If any errors occurred, you will need to correct them. 如果你得到了 uwsgi: unrecognized option '--ini-paste-logged' , make sure you are specifying the python3 plugin.

    如果出现这样的错误:

    Fatal Python error: Py_Initialize: Unable to get the locale encoding
    ModuleNotFoundError: No module named 'encodings'
    

    检查一下 virtualenv 期权在 [uwsgi] 你的部分 .ini file points to the correct directory. Specifically, it should end in env 不是 bin .

    对于任何其他导入错误,这可能意味着该包未安装或用户无法访问。这就是为什么我们选择伪装成您登录时的普通用户,所以您一定可以访问已安装的软件包。

    logto 在中被注释掉 production.ini .

  9. 在添加新文件 /etc/nginx/sites-enabled/myproject.conf 包含以下内容。同时更改单词的任何出现 ubuntu to your actual username.

     1server{
     2  server_name _;
     3
     4  root /home/ubuntu/myproject/;
     5
     6  location /  {
     7    include uwsgi_params;
     8    # The socket location must match that used by uWSGI
     9    uwsgi_pass unix:/home/ubuntu/myproject/tmp/myproject.sock;
    10  }
    11}
    
  10. 如果有文件在 /var/nginx/sites-enabled/default , remove it so your new nginx config file will catch all traffic. (如果 default is in use and important, simply add a real server_name/etc/nginx/sites-enabled/myproject.conf

  11. 重载NGNIX。

    $ sudo nginx -s reload
    
  12. 在浏览器中访问http://localhost。交替呼叫 curl localhost 从一个终端。您应该看到呈现的示例应用程序。

  13. 如果应用程序不呈现,跟踪nginx日志,然后刷新浏览器窗口(或调用 curl localhost ) again to determine the cause. (uWSGI should still be running in a separate terminal window.)

    $ cd /var/log/nginx
    $ tail -f error.log access.log
    

    如果你看到一个 No such file or directory error in the nginx error log, verify the name of the socket file specified in /etc/nginx/sites-enabled/myproject.conf . Verify that the file referenced there actually exists. If it does not, check what location is specified for socket 在你 .ini 文件,并验证指定文件是否实际存在。一旦UWSGI和NGNIX都指向同一个文件,并且两个文件都可以访问其包含的目录,则您将超过这个错误。如果所有其他的都失败了,把你的插槽放在所有可写的地方,比如 /tmp .

    如果你看到一个 upstream prematurely closed connection while reading response header from upstream nginx错误日志中有错误,应用程序或Uwsgi调用它的方式有问题。检查UWSGI仍在运行的窗口的输出,查看当您 curl localhost .

    如果你看到一个 Connection refused error in the nginx error log, check the permissions on the socket file that nginx says it is attempting to connect to. The socket file is expected to be owned by the user ubuntu 和小组 www-data because those are the uidgid 我们在 .ini 文件。If the socket file is owned by a different user or group than these, correct the uWSGI parameters in your .ini 文件。

    If you are still getting a Connection refused NGIX错误日志中的错误,检查套接字文件的权限。预期权限为 020 由你设定 .ini 文件。这个 2 in the middle of 020 www-data ) must have write permissions to it or it will not be able to connect. You can use permissions more open than 020 , but in testing this tutorial 020 was all that was required.

  14. 一旦您的应用程序可以通过nginx访问,您就有理由庆祝了。

    如果您还希望添加 uWSGI Emperor and systemd to the mix, proceed to part 2 of this tutorial: 带 cookiecutter 的UWSGI Pyramid 应用第2部分:添加 Emperor 和系统.

UWSgi有许多旋钮和多种部署模式。This is just one representation of how you might use it to serve up a cookiecutter Pyramid 应用。见 uWSGI documentation for more in-depth configuration information.

此教程是从原始教程修改而来的 Running a Pyramid Application under mod_wsgi .