如何在 Ubuntu 16.04 上使用 uWSGI 和 Nginx 为 Django 应用程序提供服务

2023-11-05

介绍

Django 是一个功能强大的 Web 框架,可以帮助您启动 Python 应用程序或网站。 Django 包含一个简化的开发服务器,用于在本地测试代码,但对于任何与生产稍微相关的事情,都需要更安全、更强大的 Web 服务器。

在本指南中,我们将演示如何在 Ubuntu 16.04 上安装和配置一些组件以支持和服务 Django 应用程序。我们将配置 uWSGI 应用程序容器服务器以与我们的应用程序交互。然后,我们将设置 Nginx 以反向代理到 uWSGI,使我们能够访问其安全和性能功能来为我们的应用程序提供服务。

先决条件和目标

为了完成本指南,您应该拥有一个新的 Ubuntu 16.04 服务器实例,其中包含一个非 root 用户sudo已配置的权限。您可以通过运行我们的初始服务器设置指南.

我们将在两个不同的虚拟环境中安装 Django。这将使您的项目及其需求能够单独处理。我们将创建两个示例项目,以便我们可以在多项目环境中运行这些步骤。

一旦我们有了应用程序,我们将安装并配置 uWSGI 应用程序服务器。这将作为我们的应用程序的接口,它将使用 HTTP 的客户端请求转换为我们的应用程序可以处理的 Python 调用。然后,我们将在 uWSGI 之前设置 Nginx,以利用其高性能连接处理机制和易于实现的安全功能。

让我们开始吧。

安装和配置 VirtualEnv 和 VirtualEnvWrapper

我们将在自己的虚拟环境中安装 Django 项目,以隔离每个项目的需求。为此,我们将安装virtualenv,它可以创建Python虚拟环境,以及virtualenvwrapper,这增加了一些可用性改进virtualenv工作流程。

我们将使用以下命令安装这两个组件pip,Python 包管理器。我们可以从 Ubuntu 存储库安装这个实用程序。

如果您正在构建 Django 项目Python 2, type:

  1. sudo apt-get update
  2. sudo apt-get installpython-pip

如果您正在使用Python 3, type:

  1. sudo apt-get update
  2. sudo apt-get installpython3-pip

现在你已经pip已安装,我们可以安装virtualenv and virtualenvwrapper全球。我们也会升级pip使用最新版本pip itself.

如果您正在使用Python 2, type:

  1. sudo -H pip install - 升级 pip
  2. sudo -H pip installvirtualenv 虚拟环境包装器

如果您正在使用Python 3, type:

  1. sudo -H pip3 install - 升级 pip
  2. sudo -H pip3 installvirtualenv 虚拟环境包装器

安装这些组件后,我们现在可以使用与 shell 一起工作所需的信息来配置 shellvirtualenvwrapper脚本。我们的虚拟环境将全部放置在我们的主文件夹中名为Env以便于访问。这是通过一个名为的环境变量配置的WORKON_HOME。我们可以将其添加到 shell 初始化脚本中,并且可以获取虚拟环境包装器脚本。

如果您正在使用Python 3pip3命令,您还必须在 shell 初始化脚本中添加一行:

  1. echo “导出 VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3” >>~/.bashrc

无论您使用哪个版本的Python,都需要运行以下命令:

  1. echo “导出 WORKON_HOME=~/Env” >>~/.bashrc
  2. echo “源/usr/local/bin/virtualenvwrapper.sh” >>~/.bashrc

现在,获取您的 shell 初始化脚本,以便您可以在当前会话中使用此功能:

  1. source~/.bashrc

您现在应该有一个名为Env在您的主文件夹中,该文件夹将保存虚拟环境信息。

创建 Django 项目

现在我们有了虚拟环境工具,我们将创建两个虚拟环境,在每个虚拟环境中安装 Django,并启动两个项目。

创建第一个项目

我们可以通过使用一些命令轻松创建虚拟环境virtualenvwrapper脚本可供我们使用。

通过键入以下内容,使用您的第一个站点或项目的名称创建您的第一个虚拟环境:

  1. mkvirtualenv firstsite

This will create a virtual environment, install Python and pip within it, and activate the environment. Your prompt will change to indicate that you are now operating within your new virtual environment. It will look something like this: (firstsite)user@hostname:~$. The value in the parentheses is the name of your virtual environment. Any software installed through pip will now be installed into the virtual environment instead of on the global system. This allows us to isolate our packages on a per-project basis.

我们的第一步是安装 Django 本身。我们可以用pip为此,无需sudo因为我们是在虚拟环境中本地安装它:

  1. pip install django

安装 Django 后,我们可以通过键入以下内容来创建第一个示例项目:

  1. cd ~
  2. django-admin.py startproject firstsite

This will create a directory called firstsite within your home directory. Within this is a management script used to handle various aspects of the project and another directory of the same name used to house the actual project code.

进入第一级目录,以便我们可以开始为示例项目设置最低要求。

  1. cd ~/firstsite

首先迁移数据库以初始化我们的项目将使用的 SQLite 数据库。如果您愿意,您可以为您的应用程序设置替代数据库,但这超出了本指南的范围:

  1. ~/firstsite/manage.py migrate

您现在应该有一个名为的数据库文件db.sqlite3在你的项目目录中。现在,我们可以通过键入以下内容来创建管理用户:

  1. ~/firstsite/manage.py createsuperuser

At this point, your project directory (~/firstsite in our case) should have the following content:

  • ~/firstsite/manage.py:一个 Django 项目管理脚本。
  • ~/firstsite/firstsite/:Django项目包。这应该包含__init__.py, settings.py, urls.py, and wsgi.py files.
  • ~/firstsite/db.sqlite3:用于存储站点信息的SQLite数据库文件。

接下来,使用文本编辑器打开项目的设置文件:

  1. nano ~/firstsite/firstsite/settings.py

首先找到ALLOWED_HOSTS指示。这定义了可用于连接到 Django 实例的服务器地址或域名的列表。任何带有Host不在此列表中的标头将引发异常。 Django 要求您设置此项以防止某种类型的安全漏洞。

在方括号中,列出与您的 Django 服务器关联的 IP 地址或域名。每个项目都应列在引号中,条目之间用逗号分隔。如果您希望请求整个域和任何子域,请在条目开头添加一个句点。在下面的代码片段中,有一些注释掉的示例用于演示:

〜/firstsite/firstsite/settings.py
. . .
# The simplest case: just add the domain name(s) and IP addresses of your Django server
# ALLOWED_HOSTS = [ 'example.com', '203.0.113.5']
# To respond to 'example.com' and any subdomains, start the domain with a dot
# ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . .]

由于我们将设置 Nginx 来为我们的站点提供服务,因此我们需要配置一个目录来保存站点的静态资产。这将允许 Nginx 直接为这些提供服务,这将对性能产生积极的影响。我们将告诉 Django 将它们放入名为的目录中static在我们项目的基本目录中。将此行添加到文件底部以配置此行为:

〜/firstsite/firstsite/settings.py
. . .
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

完成后保存并关闭文件。现在,收集我们网站的静态元素并将它们放置在该目录中,输入:

  1. ~/firstsite/manage.py collectstatic

系统可能会要求您输入“是”以确认操作并收集静态内容。将会有一个新目录名为static在你的项目目录中。

接下来,我们可以打开一个端口,以便我们可以访问Django开发服务器。如果您遵循初始服务器设置指南,则应该启用 UFW 防火墙。通过键入以下内容允许连接到端口 8080:

  1. sudoUFW 允许8080

完成所有这些后,我们可以通过临时启动开发服务器来测试我们的项目。类型:

  1. ~/firstsite/manage.py runserver 0.0.0.0:8080

这将在端口上启动开发服务器8080。访问您的服务器的域名或IP地址,然后8080在您的浏览器中:

http://server_domain_or_IP:8080

您应该看到如下所示的页面:

Django sample site

Add /admin添加到浏览器地址栏中 URL 的末尾,您将进入管理员登录页面:

Django admin login

使用您选择的管理登录凭据createsuperuser命令,登录服务器。然后您将可以访问管理界面:

Django admin interface

测试此功能后,通过键入停止开发服务器CTRL-C在您的终端中。我们现在可以继续我们的第二个项目。

创建第二个项目

第二个项目的创建方式与第一个项目完全相同。我们将在本节中简化解释,看看您是否已经完成了这一次。

返回到您的主目录并为您的新项目创建第二个虚拟环境。激活后,在这个新环境中安装 Django:

  1. cd ~
  2. mkvirtualenv secondsite
  3. pip install django

新的环境将被创建and更改为,离开您以前的虚拟环境。该 Django 实例与您配置的另一个实例完全独立。这使您可以独立管理它们并根据需要进行自定义。

创建第二个项目并进入项目目录:

  1. cd ~
  2. django-admin.py startproject secondsite
  3. cd ~/secondsite

初始化数据库并创建管理用户:

  1. ~/secondsite/manage.py migrate
  2. ~/secondsite/manage.py createsuperuser

打开设置文件:

  1. nano ~/secondsite/secondsite/settings.py

Set the ALLOWED_HOSTS到您的第二个项目的域、服务器的 IP 地址或两者,就像您对第一个项目所做的那样:

ALLOWED_HOSTS = ['second_project_domain_or_IP', 'another_domain_or_IP', . . .]

添加静态文件的位置,就像您在上一个项目中所做的那样:

〜/第二站点/第二站点/settings.py
. . .
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

保存并关闭文件。现在,通过键入以下内容将静态元素收集到该目录中:

  1. ~/secondsite/manage.py collectstatic

最后,启动开发服务器来测试该站点:

  1. ~/secondsite/manage.py runserver 0.0.0.0:8080

您应该检查常规网站:

http://server_domain_or_IP:8080

同时登录管理站点:

http://server_domain_or_IP:8080/admin

当您确认一切都按预期工作时,请输入CTRL-C在您的终端中停止开发服务器。

退出虚拟环境

由于我们现在已经完成了指南的 Django 部分,因此我们可以停用第二个虚拟环境:

  1. 停用

如果您需要再次在任一 Django 站点上工作,您应该重新激活它们各自的环境。您可以通过使用来做到这一点workon命令:

  1. workon firstsite

Or:

  1. workon secondsite

再次,当您完成网站工作后停用:

  1. 停用

我们现在可以继续配置应用程序服务器。

设置uWSGI应用服务器

现在我们已经设置了两个 Django 项目并准备就绪,我们可以配置 uWSGI。 uWSGI是一个应用程序服务器,可以通过称为WSGI的标准接口与应用程序进行通信。要了解更多相关信息,请阅读本节我们在 Ubuntu 14.04 上设置 uWSGI 和 Nginx 的指南。

安装uWSGI

与上面链接的指南不同,在本教程中,我们将全局安装 uWSGI。这将减少处理多个 Django 项目时的摩擦。在安装uWSGI之前,我们需要该软件所依赖的Python开发文件。我们可以直接从 Ubuntu 的存储库安装它。

如果您使用 DjangoPython 2, type:

  1. sudo apt-get install蟒蛇开发

如果您正在使用Python 3, type:

  1. sudo apt-get installpython3-dev

现在开发文件已经可用,我们可以通过以下方式全局安装uWSGIpip.

如果您正在使用Python 2, type:

  1. sudo -H pip install uwsgi

如果您正在使用Python 3, type:

  1. sudo -H pip3 install uwsgi

我们可以通过向该应用程序服务器传递我们站点之一的信息来快速测试该应用程序服务器。例如,我们可以通过输入以下命令来告诉它为我们的第一个项目提供服务:

  1. uwsgi --http :8080 --home /home/sammy/Env/firstsite --chdir /home/sammy/firstsite -w firstsite.wsgi

Here, we’ve told uWSGI to use our virtual environment located in our ~/Env directory, to change to our project’s directory, and to use the wsgi.py file stored within our inner firstsite directory to serve the file (using the firstsite.wsgi Python module syntax). For our demonstration, we told it to serve HTTP on port 8080.

如果您在浏览器中访问服务器的域名或IP地址,然后输入:8080,您将再次看到您的网站(静态元素/admin界面(如 CSS)还无法工作)。测试完此功能后,请在终端中键入 CTRL-C。

创建配置文件

从命令行运行 uWSGI 对于测试很有用,但对于实际部署并不是特别有帮助。相反,我们将以“皇帝模式”运行uWSGI,这允许主进程在给定一组配置文件的情况下自动管理单独的应用程序。

创建一个目录来保存您的配置文件。由于这是一个全局过程,我们将创建一个名为的目录/etc/uwsgi/sites存储我们的配置文件:

  1. sudo mkdir -p/etc/uwsgi/站点

在这个目录中,我们将放置我们的配置文件。我们需要为我们服务的每个项目提供一个配置文件。 uWSGI进程可以采用多种格式的配置文件,但我们将使用.ini文件,因为它们的简单性。

为您的第一个项目创建一个文件并在文本编辑器中打开它:

  1. sudo nano /etc/uwsgi/sites/firstsite.ini

在内部,我们必须从[uwsgi]节标题。我们所有的信息都将位于此标题下方。我们还将使用变量来使我们的配置文件更加可重用。在标题之后,设置一个名为的变量project与您的第一个项目的名称。添加一个名为uid其中包含你的sudo用户名。

我们还将添加一个名为的变量base以及用户主目录的路径。这将从我们使用设置的用户名构建%(variable_name)句法。当读取配置时,这将被变量的值替换:

/etc/uwsgi/sites/firstsite.ini
[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)

接下来,我们需要配置uWSGI,以便它正确处理我们的项目。我们需要通过设置更改为根项目目录chdir选项。我们可以使用相同的变量语法组合主目录和项目名称。

以类似的方式,我们将为我们的项目指定虚拟环境。通过设置模块,我们可以准确地指示如何与我们的项目交互(通过导入可从wsgi.py我们的内部项目目录中的文件)。这些项目的配置如下所示:

/etc/uwsgi/sites/firstsite.ini
[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

我们想要创建一个有 5 个工作线程的主进程。我们可以通过添加以下内容来做到这一点:

/etc/uwsgi/sites/firstsite.ini
[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

master = true
processes = 5

接下来我们需要指定uWSGI应该如何监听连接。在我们对 uWSGI 的测试中,我们使用了 HTTP 和网络端口。然而,由于我们将使用 Nginx 作为反向代理,因此我们有更好的选择。

由于所有组件都在单个服务器上运行,因此我们可以使用 Unix 套接字,而不是使用网络端口。这更安全并提供更好的性能。该套接字不会使用 HTTP,而是实现 uWSGIuwsgi协议,这是一种快速二进制协议,设计用于与其他服务器通信。 Nginx 可以使用本机代理uwsgi协议,所以这是我们最好的选择。

我们还将修改套接字的所有权和权限,因为我们将授予 Web 服务器写访问权限。我们将设置vacuum选项以便在服务停止时自动清理套接字文件:

/etc/uwsgi/sites/firstsite.ini
[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

master = true
processes = 5

socket = /run/uwsgi/%(project).sock
chown-socket = %(uid):www-data
chmod-socket = 660
vacuum = true

至此,我们第一个项目的uWSGI配置就完成了。保存并关闭文件。

使用变量设置文件的优点是它使得重用变得非常简单。复制第一个项目的配置文件以用作第二个配置文件的基础:

  1. sudo cp /etc/uwsgi/sites/firstsite.ini /etc/uwsgi/sites/secondsite.ini

使用文本编辑器打开第二个配置文件:

  1. sudo nano /etc/uwsgi/sites/secondsite.ini

我们只需更改此文件中的单个值即可使其适用于我们的第二个项目。修改project变量的名称是您在第二个项目中使用的名称:

/etc/uwsgi/sites/secondsite.ini
[uwsgi]
project = secondsite
uid = sammy
base = /home/%(uid)

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

master = true
processes = 5

socket = /run/uwsgi/%(project).sock
chown-socket = %(uid):www-data
chmod-socket = 660
vacuum = true

完成后保存并关闭文件。您的第二个项目现在应该可以开始了。

为uWSGI创建一个systemd单元文件

我们现在拥有了为 Django 项目提供服务所需的配置文件,但我们仍然没有自动化该过程。接下来,我们将创建一个systemd单元文件来管理uWSGIemperor进程并在启动时自动启动uWSGI。

我们将在以下位置创建单元文件/etc/systemd/system目录,其中保存管理员创建的单元文件。我们将调用我们的文件uwsgi.service:

  1. sudo nano/etc/systemd/system/uwsgi.service

[Unit]部分,用于指定元数据和排序信息。我们将在这里简单地描述我们的服务:

/etc/systemd/system/uwsgi.service
[Unit]
Description=uWSGI Emperor service

接下来我们将开放[Service]部分。我们将使用ExecStartPre指令来设置我们运行服务器所需的部分。这将确保/run/uwsgi目录已创建,并且我们的普通用户拥有该目录www-data组作为组所有者。两个都mkdir-p旗帜和chown即使不需要它们的操作,命令也会成功返回。这就是我们想要的。

对于实际的启动命令,由ExecStart指令,我们将指向uwsgi可执行的。我们将告诉它以“皇帝模式”运行,允许它使用它在其中找到的文件来管理多个应用程序/etc/uwsgi/sites。我们还将添加 systemd 正确管理进程所需的部分。这些取自uWSGI文档here.

/etc/systemd/system/uwsgi.service
[Unit]
Description=uWSGI Emperor service

[Service]
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown sammy:www-data /run/uwsgi'
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

现在,我们需要做的就是添加[Install]部分。这允许我们指定服务何时自动启动。我们将把我们的服务与多用户系统状态联系起来。每当系统设置为多个用户(正常操作条件)时,我们的服务就会被激活:

/etc/systemd/system/uwsgi.service
[Unit]
Description=uWSGI Emperor service

[Service]
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown sammy:www-data /run/uwsgi'
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

[Install]
WantedBy=multi-user.target

完成后,保存并关闭文件。

此时我们将无法成功启动该服务,因为它依赖于www-data用户可用。我们必须等到 Nginx 安装后才能启动 uWSGI 服务。

安装 Nginx 并将其配置为反向代理

配置好 uWSGI 并准备就绪后,我们现在可以安装并配置 Nginx 作为我们的反向代理。这可以从 Ubuntu 的默认存储库下载:

  1. sudo apt-get install nginx

安装 Nginx 后,我们可以继续为每个项目创建一个服务器块配置文件。通过创建服务器块配置文件从第一个项目开始:

  1. sudo nano /etc/nginx/sites-available/firstsite

在内部,我们可以通过指示应可访问第一个项目的端口号和域名来启动服务器块。这server_name block must匹配服务器的域名或其 IP 地址之一,否则可能会使用默认的 Nginx 页面。我们假设您每个都有一个域名:

/etc/nginx/sites-available/firstsite
server {
    listen 80;
    server_name firstsite.com www.firstsite.com;
}

接下来,我们可以告诉 Nginx 如果找不到图标,不用担心。我们还将其指向我们收集网站静态元素的静态文件目录的位置:

/etc/nginx/sites-available/firstsite
server {
    listen 80;
    server_name firstsite.com www.firstsite.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/sammy/firstsite;
    }
}

接下来,我们可以创建一个包罗万象的位置块,它将所有其他查询直接传递到我们的应用程序。我们将包括uwsgi中找到的参数/etc/nginx/uwsgi_params并将流量传递到uWSGI服务器设置的套接字:

/etc/nginx/sites-available/firstsite
server {
    listen 80;
    server_name firstsite.com www.firstsite.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/sammy/firstsite;
    }

    location / {
        include         uwsgi_params;
        uwsgi_pass      unix:/run/uwsgi/firstsite.sock;
    }
}

至此,我们的第一个服务器块就完成了。

我们将使用它作为第二个项目的 Nginx 配置文件的基础。现在复制过来:

  1. sudo cp /etc/nginx/sites-available/firstsite /etc/nginx/sites-available/secondsite

在文本编辑器中打开新文件:

  1. sudo nano /etc/nginx/sites-available/secondsite

Here, you’ll have to change any reference to firstsite with a reference to secondsite. You’ll also have to modify the server_name so that your second project responds to a different domain name or change the port if you don’t have more than one domain name or IP address. When you are finished, it will look something like this:

/etc/nginx/sites-available/secondsite
server {
    listen 80;
    server_name secondsite.com www.secondsite.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/sammy/secondsite;
    }

    location / {
        include         uwsgi_params;
        uwsgi_pass      unix:/run/uwsgi/secondsite.sock;
    }
}

完成后保存并关闭文件。

接下来,将两个新配置文件链接到 Nginx 的sites-enabled启用它们的目录:

  1. sudo ln -s /etc/nginx/sites-available/firstsite /etc/nginx/sites-enabled
  2. sudo ln -s /etc/nginx/sites-available/secondsite /etc/nginx/sites-enabled

通过键入以下内容检查配置语法:

  1. sudo nginx -t

如果没有检测到语法错误,您可以重新启动 Nginx 服务以加载新配置:

  1. sudosystemctl 重新启动 nginx

如果您还记得之前,我们从未真正启动过 uWSGI 服务器。现在输入:

  1. sudosystemctl 启动 uwsgi

让我们删除要端口的 UFW 规则8080并允许访问我们的 Nginx 服务器:

  1. sudoufw 删除允许8080
  2. sudoUFW 允许“Nginx 已满”

您现在应该能够通过访问各自的域名来访问您的两个项目。公共和管理界面都应按预期工作。

如果一切顺利,您可以通过键入以下内容使这两个服务在启动时自动启动:

  1. sudo系统控制enable nginx
  2. sudo系统控制enable uwsgi

Note

配置 Nginx 后,下一步应该是使用 SSL/TLS 保护服务器的流量。这很重要,因为没有它,所有信息(包括密码)都将以纯文本形式通过网络发送。

如果您有域名,获取 SSL 证书来保护流量的最简单方法是使用 Let’s Encrypt。跟随本指南在 Ubuntu 16.04 上设置 Let’s Encrypt with Nginx。

如果您没有域名,您仍然可以通过以下方式保护您的网站以进行测试和学习:自签名 SSL 证书.

Nginx 和 uWSGI 故障排除

如果您无法访问您的应用程序,则需要对安装进行故障排除。

Nginx 显示默认页面而不是 Django 应用程序

If Nginx displays the default page instead of proxying to your application, it usually means that you need to adjust the server_name within the /etc/nginx/sites-available/firstsite file to point to your server’s IP address or domain name.

Nginx 使用server_name确定使用哪个服务器块来响应请求。如果您看到默认的 Nginx 页面,则表明 Nginx 无法显式地将请求与服务器块匹配,因此它会退回到定义的默认块/etc/nginx/sites-available/default.

The server_name您项目的服务器块中的服务器块必须比要选择的默认服务器块中的服务器块中的服务器块更具体。

Nginx 显示 502 Bad Gateway 错误而不是 Django 应用程序

502错误表示Nginx无法成功代理请求。许多配置问题都会通过 502 错误来表达,因此需要更多信息才能正确排除故障。

查找更多信息的主要位置是 Nginx 的错误日志。一般来说,这会告诉您代理事件期间哪些条件导致了问题。通过键入以下内容来跟踪 Nginx 错误日志:

  1. sudo tail -F/var/log/nginx/error.log

现在,在浏览器中发出另一个请求以生成新的错误(尝试刷新页面)。您应该会看到一条新的错误消息写入日志。如果您查看该消息,它应该可以帮助您缩小问题范围。

您可能会看到以下一些消息:

connect() 到 unix:/run/uwsgi/firstsite.sock 失败(2:没有这样的文件或目录)

这表明 Nginx 无法在给定位置找到套接字文件。你应该比较uwsgi_pass中定义的位置firstsite and secondsite文件在/etc/nginx/sites-available文件的实际位置firstsite.sock and secondsite.sock套接字文件在/run/uwsgi目录。

检查套接字文件是否存在/run/uwsgi目录,输入:

  1. sudo ls/运行/uwsgi

如果没有socket文件/run/uwsgi,一般意味着uwsgi进程无法创建它。检查状态uwsgi查明是否能够启动的过程:

  1. sudosystemctl 状态 uwsgi

If the systemctl status命令表明发生了错误,或者如果在目录中没有找到套接字文件,则表明uWSGI无法正确启动。通过键入以下内容检查 uWSGI 进程日志:

  1. sudo日志控制-u uwsgi

查看日志中的消息以找出 uWSGI 遇到问题的位置。有很多原因可能会导致您遇到问题,但通常,如果 uWSGI 无法创建套接字文件,则可能是由于以下原因之一:

  • 项目文件的所有者是root用户而不是sudo user
  • The ExecStartPre线在/etc/systemd/system/uwsgi.service文件不包含创建目录和分配所有权的正确命令
  • The uwsgi_pass站点配置文件中的路径/etc/nginx/sites-available目录没有针对正确的套接字位置
  • The uWSGI configuration defined in the .ini files within the /etc/uwsgi/sites directory is incorrect. Check the following items:
    • The chdir指令一旦插入,就指向主项目目录。
    • The home指令一旦插入,就指向虚拟环境目录。
    • The module指令使用 Python 模块导入语法来加载wsgi.py文件来自内部项目目录。
    • The socket指令指向一个文件/run/uwsgi文件(应该由ExecStartPre上述服务文件中的行)。

如果您对/etc/systemd/system/uwsgi.service文件中,重新加载守护进程以重新读取服务定义并通过键入以下内容重新启动 uWSGI 进程:

  1. sudosystemctl 守护进程重新加载
  2. sudosystemctl 重新启动 uwsgi

修复这些问题应该可以让 Nginx 正确找到套接字文件。

connect() 到 unix:/run/uwsgi/firstsite.sock 失败(13:权限被拒绝)

这表明 Nginx 由于权限问题而无法连接到 uWSGI 套接字。通常,当在受限环境中创建套接字或权限错误时,会发生这种情况。虽然uWSGI进程能够创建套接字文件,但Nginx无法访问它。

如果根目录(/) 套接字文件。通过将套接字文件的绝对路径传递给namei命令:

  1. namei -nom/run/uwsgi/firstsite.sock
Output
f: /run/uwsgi/firstsite.sock drwxr-xr-x root root / drwxr-xr-x root root run drwxr-xr-x sammy www-data uwsgi srw-rw---- sammy www-data firstsite.sock

输出显示每个目录组件的权限。通过查看权限(第一列)、所有者(第二列)和组所有者(第三列),我们可以弄清楚套接字文件允许什么类型的访问。

在上面的示例中,通向套接字文件的每个目录都具有全局读取和执行权限(目录的权限列以r-x代替---). The www-datagroup 对套接字本身拥有组所有权。通过这些设置,Nginx 进程应该能够成功访问套接字。

如果通向套接字的任何目录不属于www-data组或没有世界读取和执行权限,Nginx 将无法访问套接字。通常,这意味着配置文件有错误。

如果目录路径的权限或所有权限制过多,请查看/etc/systemd/system/uwsgi.service文件。这ExecStartPre指令负责创建/run/uwsgi目录并将组所有权分配给www-data团体。如果此处的命令不正确,则目录路径可能限制过多。

如果 Nginx 进程无法访问套接字文件本身,则在.ini内的文件/etc/uwsgi/sites可能是不正确的。检查以下值chown-socket and chmod-socket以确保 Web 进程有权访问这些文件。

进一步排除故障

对于其他故障排除,日志可以帮助缩小根本原因的范围。依次检查每一个并查找指示问题区域的消息。

以下日志可能会有所帮助:

  • 通过键入以下内容检查 Nginx 进程日志:sudo journalctl -u nginx
  • 通过键入以下内容检查 Nginx 访问日志:sudo less /var/log/nginx/access.log
  • 通过键入以下内容检查 Nginx 错误日志:sudo less /var/log/nginx/error.log
  • 通过键入以下内容检查 uWSGI 应用程序日志:sudo journalctl -u uwsgi

当您更新配置或应用程序时,您可能需要重新启动进程以适应您的更改。

如果您更新 Django 应用程序,您可以通过键入以下内容重新启动 uWSGI 进程以获取更改:

  1. sudosystemctl 重新启动 uwsgi

如果你改变uwsgisystemd 服务文件,重新加载守护进程并通过键入以下内容重新启动进程:

  1. sudosystemctl 守护进程重新加载
  2. sudosystemctl 重新启动 uwsgi

如果更改 Nginx 服务器块配置,请测试配置,然后输入以下命令测试 Nginx:

  1. sudo nginx -t && sudosystemctl 重新启动 nginx

这些命令有助于在您调整配置时获取更改。

结论

在本指南中,我们设置了两个 Django 项目,每个项目都在自己的虚拟环境中。我们已经将 uWSGI 配置为使用为每个项目配置的虚拟环境独立地为每个项目提供服务。之后,我们设置 Nginx 作为反向代理来处理客户端连接并根据客户端请求提供正确的项目。

Django 通过提供许多通用部分使创建项目和应用程序变得简单,使您能够专注于独特的元素。通过利用本文中描述的通用工具链,您可以轻松地为从单个服务器创建的应用程序提供服务。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Ubuntu 16.04 上使用 uWSGI 和 Nginx 为 Django 应用程序提供服务 的相关文章

  • 用于渲染 html 子集的 Django templatetag

    我有一些 html 在本例中是通过 TinyMCE 创建的 我想将其添加到页面中 但是 出于安全原因 我不想只打印用户输入的所有内容 有谁知道模板标签 最好是过滤器 只允许呈现 html 的安全子集 我意识到 Markdown 和其他人就是
  • 雅虎财务请求功能出现 404 客户端错误

    yahoo Financials的请求功能出现404 Client Error 直接点击以下网址没有问题 https finance yahoo com quote AAPL financials p AAPL https finance
  • 在 django 中自定义项目和应用程序模板

    我想自定义运行时创建的文件和文件夹 python manage py startapp appname 我发现一遍又一遍地做一些事情 我认为如果在创建新应用程序时存在我的自定义功能 那就太好了 您知道创建应用程序时可以在哪里自定义默认文件吗
  • 使用pathlib获取主目录

    翻看新的pathlib在 Python 3 4 中 我注意到没有任何简单的方法来获取用户的主目录 我能想到的获取用户主目录的唯一方法是使用旧的os path像这样的库 import pathlib from os import path p
  • 用 Python 绘制直方图

    我有两个列表 x 和 y x 包含字母表 A Z Y 包含它们在文件中的频率 我尝试研究如何在直方图中绘制这些值 但在理解如何绘制它方面没有成功 n bins patches plt hist x 26 normed 1 facecolor
  • 为什么 re.findall 在查找字符串中的三元组项时不具体。 Python

    所以我有四行代码 seq ATGGAAGTTGGATGAAAGTGGAGGTAAAGAGAAGACGTTTGA OR 0 re findall r ATG 9 TAA TAG TGA seq 首先让我解释一下我正在尝试做什么 如果这令人困惑
  • Py2exe - Pmw WindowsError:[错误 3]

    我正在尝试使用 Py2exe 构建独立的可执行文件 我已经导入了 Pmw 类 当我运行独立可执行文件时 出现以下错误 Traceback most recent call last File py line 9 in
  • Ubuntu 12.10 libgtk-3-0 缺少符号

    我正在运行 Ubuntu 12 10 不知何故我的 libgtk 3 0 搞砸了 当尝试运行许多不同的应用程序时 我收到如下错误 gedit symbol lookup error usr lib libgtk 3 so 0 undefin
  • 使用 if 语句的网格网格和用户定义函数的真值不明确

    假设我有一个函数f x y 足够光滑 然而 有些值仅在有限的意义上存在 以sin x x的价值x 0只存在于极限 x gt 0 中 在一般情况下 我用一个来处理这个问题if陈述 如果我在情节中使用它meshgrid我收到一条错误消息 Val
  • Python:在字典中查找具有唯一值的键?

    我收到一个字典作为输入 并且想要返回一个键列表 其中字典值在该字典的范围内是唯一的 我将用一个例子来澄清 假设我的输入是字典 a 构造如下 a dict a cat 1 a fish 1 a dog 2 lt unique a bat 3
  • 无法使用 python rasterio、gdal 打开 jp2 (来自哨兵)

    我试图在 python 中将 jp2 栅格产品作为栅格打开 但当我们使用 raterio 和 gdal 包时没有成功 我收到此错误 RasterioIOError b4 jp2 not recognized as a supported f
  • Django 2、python 3.4 无法解码 urlsafe_base64_decode(uidb64)

    我正在尝试通过电子邮件激活用户 电子邮件有效 编码有效 我使用了 django1 11 中的方法 该方法运行成功 在 Django 1 11 中 以下内容成功解码为 28 其中 uidb64 b Mjg force text urlsafe
  • 为什么 Collections.counter 这么慢?

    我正在尝试解决罗莎琳德的基本问题 即计算给定序列中的核苷酸 并在列表中返回结果 对于那些不熟悉生物信息学的人来说 它只是计算字符串中 4 个不同字符 A C G T 出现的次数 我期望collections Counter是最快的方法 首先
  • 如何获取分类数据的分组条形图

    I have a big dataset with information about students And I have to build a graph of dependencies between different value
  • 如何通过 Python Requests 库使用基本 HTTP 身份验证?

    我正在尝试在 Python 中使用基本的 HTTP 身份验证 我正在使用Requests https docs python requests org 图书馆 auth requests post http hostname auth HT
  • 如何展平解析树并存储在字符串中以进行进一步的字符串操作 python nltk

    我正在尝试从树结构中获取扁平树 如下所示 我想将整个树放在一个字符串中 就像没有检测到坏树错误一样 S NP SBJ NP DT The JJ high JJ seven day PP IN of NP DT the CD 400 NNS
  • pandas.read_fwf 忽略提供的数据类型

    我正在从文本文件导入数据框 我想指定列的数据类型 但 pandas 似乎忽略了dtype input 一个工作示例 from io import StringIO import pandas as pd string USAF WBAN S
  • 使用 MPI 的 Allreduce 对 Python 对象求和

    我正在使用使用 Python 中的字典和计数器构建的稀疏张量数组操作 我想让并行使用这个数组操作成为可能 最重要的是 我最终在每个节点上都有计数器 我想使用 MPI Allreduce 或另一个不错的解决方案 将其添加在一起 例如 使用计数
  • 为boost python编译的.so找不到模块

    我正在尝试将 C 代码包装到 python 中 只需一个类即可导出两个函数 我编译为map so 当我尝试时import map得到像噪音一样的错误 Traceback most recent call last File
  • 如何使用 Python/Django 在 Facebook 中获取(和使用)扩展权限

    我正在尝试编写一个简单的应用程序 让用户授予我的代码写入其页面的 Facebook 流的权限 据我了解 它应该很简单 让用户单击一个按钮 启动一个弹出窗口 其中包含我的 Facebook 应用程序中的页面 在该页面中 他们单击授予的内容流发

随机推荐

  • 如何在 Linux、Windows 和 macOS 上编辑 Hosts 文件

    Hosts 文件用于将域名 主机名 映射到 IP 地址 它是所有操作系统 包括 Linux Windows 和 macOS 都使用的纯文本文件 主机文件的优先级高于 DNS 当您输入要访问的网站的域名时 必须将域名转换为其相应的IP地址 操
  • Bash 连接字符串

    最常用的字符串操作之一是连接 字符串连接只是一个奇特的编程术语 用于通过将一个字符串附加到另一个字符串的末尾来将字符串连接在一起 在本教程中 我们将解释如何在 Bash 中连接字符串 连接字符串 连接两个或多个字符串变量的最简单方法是将它们
  • 如何在 Debian 9 上安装和使用 Docker Compose

    Docker 组合是一个允许您定义和编排多容器 Docker 应用程序的工具 它使用 YAML 文件来配置应用程序的容器 网络和卷 Compose 可用于多种目的 单主机应用程序部署 自动化测试和本地开发是 Docker Compose 最
  • 如何在 Debian 10 Linux 上安装 Apache Web 服务器

    Apache HTTP 服务器是世界上最流行的 Web 服务器之一 它是一个开源 跨平台的 HTTP 服务器 为大部分互联网网站提供支持 Apache 提供了许多强大的功能 可以通过附加模块进行扩展 在本教程中 我们将解释如何在 Debia
  • 如何在 Debian 9 上安装 PHP

    Debian 9 附带的 PHP 7 0 版本很快就会停止支持 并且不再接收安全更新 在本教程中 我们将引导您完成在 Debian 9 服务器上安装 PHP 7 2 的步骤 我们还将向您展示如何配置 Apache 和 Nginx 来运行 P
  • 如何在 Debian 9 上使用 VSFTPD 设置 FTP 服务器

    FTP 文件传输协议 是一种标准网络协议 用于在远程网络之间传输文件 为了更安全 更快速的数据传输 请使用SCP or SFTP 有许多可用于 Linux 的开源 FTP 服务器 最流行和最广泛使用的是PureFTPd ProFTPD an
  • Linux 中的 Xargs 命令

    The xargs实用程序允许您从标准输入构建和执行命令 它通常通过管道与其他命令结合使用 With xargs 您可以提供标准输入作为命令行实用程序的参数 例如mkdir and rm 在本教程中 我们将介绍使用xargs命令 如何使用L
  • 如何在 Ubuntu 18.04 上安装 Chromium Web 浏览器

    Chromium是一款专为现代网络打造的快速 稳定且安全的浏览器 它是许多浏览器的基础 包括世界上使用最广泛的网络浏览器谷歌浏览器 Chromium 和 Google Chrome 之间的主要区别在于 Chromium 是开源的 与 Chr
  • 如何在 Raspberry Pi 上安装 Node.js 和 npm

    Node js 是一个基于 Chrome 的 JavaScript 引擎构建的开源跨平台 JavaScript 运行时环境 允许服务器端执行 JavaScript 代码 它主要用于构建服务器端应用程序 但作为全栈和前端解决方案也非常流行 n
  • 如何在 Debian 9 上安装 Tomcat 9

    Apache Tomcat 是一个开源应用程序服务器 支持 Java Servlet JavaServer Pages Java 表达式语言和 Java WebSocket 技术 它是当今世界上使用最广泛的应用程序和 Web 服务器之一 本
  • 如何在 Ubuntu 18.04 上安装 PrestaShop

    普斯塔商店是一个免费开源的电子商务平台 它基于 PHP 和 MySQL 可以通过免费和高级插件和主题进行扩展 PrestaShop 具有直观的管理界面 多个支付网关 多语言 分析和报告等功能 是许多在线商家的首选平台 在本教程中 我们将向您
  • 如何在 Ubuntu 18.04 上安装 Jenkins

    Jenkins是一个开源自动化服务器 提供了一种设置持续集成和持续交付 CI CD 管道的简单方法 持续集成 CI 是一种 DevOps 实践 团队成员定期将代码更改提交到版本控制存储库 然后运行自动化构建和测试 持续交付 CD 是自动构建
  • 如何在 CentOS 7 上安装 Yarn

    Yarn 是一个与 npm 兼容的 JavaScript 包管理器 可帮助您自动执行安装 更新 配置和删除 npm 包的过程 它的创建是为了解决 npm 的一系列问题 例如通过并行操作加快软件包安装过程并减少与网络连接相关的错误 在本教程中
  • Linux 中的 Pgrep 命令

    本文涵盖了 Linux 的基础知识pgrep命令 pgrep是一个命令行实用程序 允许您根据给定条件查找正在运行的程序的进程 ID 它可以是完整或部分进程名称 运行进程的用户或其他属性 The pgrep命令是的一部分procps or p
  • 安装和配置 Postfix 和 Dovecot

    这是我们的第二篇文章设置和配置邮件服务器系列 在这篇文章中 我们将向您展示如何安装和配置 Postfix 和 Dovecot 这是我们邮件系统的两个主要组件 Postfix 是一个开源邮件传输代理 MTA 是一种用于发送和接收电子邮件的服务
  • 如何在 Debian 10 上安装 Memcached

    Memcached 是一个免费开源的高性能内存键值数据存储 它通常用于通过缓存 API 和数据库调用结果中的各种对象来加速应用程序 本文介绍如何在 Debian 10 上安装和配置 Memcached 先决条件 您需要以以下身份登录具有 s
  • Linux 中的剪切命令

    Linux 和 Unix 系统中有许多实用程序可让您处理和过滤文本文件 cut是一个命令行实用程序 允许您从指定文件或管道数据中剪切部分行并将结果打印到标准输出 它可用于按分隔符 字节位置和字符来剪切行的各个部分 在本文中 我们将向您展示如
  • 如何在 Ubuntu 12.04 x64 上安装 iRedMail

    Status 已弃用 本文介绍不再受支持的 Ubuntu 版本 如果您当前运行的服务器运行 Ubuntu 12 04 我们强烈建议您升级或迁移到受支持的 Ubuntu 版本 升级到Ubuntu 14 04 从 Ubuntu 14 04 升级
  • Spring框架

    Spring 框架是最流行的 Java EE 框架之一 在本文中 我们将了解以下内容 Spring框架架构 Spring的核心组件 spring 框架下的各种项目 我查看了 Spring Framework Servlet JSP 和 JS
  • 如何在 Ubuntu 16.04 上使用 uWSGI 和 Nginx 为 Django 应用程序提供服务

    介绍 Django 是一个功能强大的 Web 框架 可以帮助您启动 Python 应用程序或网站 Django 包含一个简化的开发服务器 用于在本地测试代码 但对于任何与生产稍微相关的事情 都需要更安全 更强大的 Web 服务器 在本指南中