Django 是一个功能强大的 Web 框架,可以帮助您启动 Python 应用程序或网站。 Django 包含一个简化的开发服务器,用于在本地测试代码,但对于任何与生产稍微相关的事情,都需要更安全、更强大的 Web 服务器。
在本指南中,我们将演示如何在 Ubuntu 16.04 上安装和配置一些组件以支持和服务 Django 应用程序。我们将配置 uWSGI 应用程序容器服务器以与我们的应用程序交互。然后,我们将设置 Nginx 以反向代理到 uWSGI,使我们能够访问其安全和性能功能来为我们的应用程序提供服务。
为了完成本指南,您应该拥有一个新的 Ubuntu 16.04 服务器实例,其中包含一个非 root 用户sudo
已配置的权限。您可以通过运行我们的初始服务器设置指南.
我们将在两个不同的虚拟环境中安装 Django。这将使您的项目及其需求能够单独处理。我们将创建两个示例项目,以便我们可以在多项目环境中运行这些步骤。
一旦我们有了应用程序,我们将安装并配置 uWSGI 应用程序服务器。这将作为我们的应用程序的接口,它将使用 HTTP 的客户端请求转换为我们的应用程序可以处理的 Python 调用。然后,我们将在 uWSGI 之前设置 Nginx,以利用其高性能连接处理机制和易于实现的安全功能。
让我们开始吧。
我们将在自己的虚拟环境中安装 Django 项目,以隔离每个项目的需求。为此,我们将安装virtualenv
,它可以创建Python虚拟环境,以及virtualenvwrapper
,这增加了一些可用性改进virtualenv
工作流程。
我们将使用以下命令安装这两个组件pip
,Python 包管理器。我们可以从 Ubuntu 存储库安装这个实用程序。
如果您正在构建 Django 项目Python 2, type:
-
sudo apt-get update
-
sudo apt-get installpython-pip
如果您正在使用Python 3, type:
-
sudo apt-get update
-
sudo apt-get installpython3-pip
现在你已经pip
已安装,我们可以安装virtualenv
and virtualenvwrapper
全球。我们也会升级pip
使用最新版本pip
itself.
如果您正在使用Python 2, type:
-
sudo -H pip install - 升级 pip
-
sudo -H pip installvirtualenv 虚拟环境包装器
如果您正在使用Python 3, type:
-
sudo -H pip3 install - 升级 pip
-
sudo -H pip3 installvirtualenv 虚拟环境包装器
安装这些组件后,我们现在可以使用与 shell 一起工作所需的信息来配置 shellvirtualenvwrapper
脚本。我们的虚拟环境将全部放置在我们的主文件夹中名为Env
以便于访问。这是通过一个名为的环境变量配置的WORKON_HOME
。我们可以将其添加到 shell 初始化脚本中,并且可以获取虚拟环境包装器脚本。
如果您正在使用Python 3和pip3
命令,您还必须在 shell 初始化脚本中添加一行:
-
echo “导出 VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3” >>~/.bashrc
无论您使用哪个版本的Python,都需要运行以下命令:
-
echo “导出 WORKON_HOME=~/Env” >>~/.bashrc
-
echo “源/usr/local/bin/virtualenvwrapper.sh” >>~/.bashrc
现在,获取您的 shell 初始化脚本,以便您可以在当前会话中使用此功能:
您现在应该有一个名为Env
在您的主文件夹中,该文件夹将保存虚拟环境信息。
现在我们有了虚拟环境工具,我们将创建两个虚拟环境,在每个虚拟环境中安装 Django,并启动两个项目。
我们可以通过使用一些命令轻松创建虚拟环境virtualenvwrapper
脚本可供我们使用。
通过键入以下内容,使用您的第一个站点或项目的名称创建您的第一个虚拟环境:
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
因为我们是在虚拟环境中本地安装它:
安装 Django 后,我们可以通过键入以下内容来创建第一个示例项目:
-
cd ~
- 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.
进入第一级目录,以便我们可以开始为示例项目设置最低要求。
首先迁移数据库以初始化我们的项目将使用的 SQLite 数据库。如果您愿意,您可以为您的应用程序设置替代数据库,但这超出了本指南的范围:
- ~/firstsite/manage.py migrate
您现在应该有一个名为的数据库文件db.sqlite3
在你的项目目录中。现在,我们可以通过键入以下内容来创建管理用户:
- ~/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数据库文件。
接下来,使用文本编辑器打开项目的设置文件:
-
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/')
完成后保存并关闭文件。现在,收集我们网站的静态元素并将它们放置在该目录中,输入:
- ~/firstsite/manage.py collectstatic
系统可能会要求您输入“是”以确认操作并收集静态内容。将会有一个新目录名为static
在你的项目目录中。
接下来,我们可以打开一个端口,以便我们可以访问Django开发服务器。如果您遵循初始服务器设置指南,则应该启用 UFW 防火墙。通过键入以下内容允许连接到端口 8080:
完成所有这些后,我们可以通过临时启动开发服务器来测试我们的项目。类型:
- ~/firstsite/manage.py runserver 0.0.0.0:8080
这将在端口上启动开发服务器8080
。访问您的服务器的域名或IP地址,然后8080
在您的浏览器中:
http://server_domain_or_IP:8080
您应该看到如下所示的页面:
Add /admin
添加到浏览器地址栏中 URL 的末尾,您将进入管理员登录页面:
使用您选择的管理登录凭据createsuperuser
命令,登录服务器。然后您将可以访问管理界面:
测试此功能后,通过键入停止开发服务器CTRL-C在您的终端中。我们现在可以继续我们的第二个项目。
第二个项目的创建方式与第一个项目完全相同。我们将在本节中简化解释,看看您是否已经完成了这一次。
返回到您的主目录并为您的新项目创建第二个虚拟环境。激活后,在这个新环境中安装 Django:
-
cd ~
- mkvirtualenv secondsite
- pip install django
新的环境将被创建and更改为,离开您以前的虚拟环境。该 Django 实例与您配置的另一个实例完全独立。这使您可以独立管理它们并根据需要进行自定义。
创建第二个项目并进入项目目录:
-
cd ~
- django-admin.py startproject secondsite
-
cd ~/secondsite
初始化数据库并创建管理用户:
- ~/secondsite/manage.py migrate
- ~/secondsite/manage.py createsuperuser
打开设置文件:
-
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/')
保存并关闭文件。现在,通过键入以下内容将静态元素收集到该目录中:
- ~/secondsite/manage.py collectstatic
最后,启动开发服务器来测试该站点:
- ~/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 部分,因此我们可以停用第二个虚拟环境:
如果您需要再次在任一 Django 站点上工作,您应该重新激活它们各自的环境。您可以通过使用来做到这一点workon
命令:
Or:
再次,当您完成网站工作后停用:
我们现在可以继续配置应用程序服务器。
现在我们已经设置了两个 Django 项目并准备就绪,我们可以配置 uWSGI。 uWSGI是一个应用程序服务器,可以通过称为WSGI的标准接口与应用程序进行通信。要了解更多相关信息,请阅读本节我们在 Ubuntu 14.04 上设置 uWSGI 和 Nginx 的指南。
与上面链接的指南不同,在本教程中,我们将全局安装 uWSGI。这将减少处理多个 Django 项目时的摩擦。在安装uWSGI之前,我们需要该软件所依赖的Python开发文件。我们可以直接从 Ubuntu 的存储库安装它。
如果您使用 DjangoPython 2, type:
如果您正在使用Python 3, type:
-
sudo apt-get installpython3-dev
现在开发文件已经可用,我们可以通过以下方式全局安装uWSGIpip
.
如果您正在使用Python 2, type:
-
sudo -H pip install uwsgi
如果您正在使用Python 3, type:
-
sudo -H pip3 install uwsgi
我们可以通过向该应用程序服务器传递我们站点之一的信息来快速测试该应用程序服务器。例如,我们可以通过输入以下命令来告诉它为我们的第一个项目提供服务:
- 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
存储我们的配置文件:
-
sudo mkdir -p/etc/uwsgi/站点
在这个目录中,我们将放置我们的配置文件。我们需要为我们服务的每个项目提供一个配置文件。 uWSGI进程可以采用多种格式的配置文件,但我们将使用.ini
文件,因为它们的简单性。
为您的第一个项目创建一个文件并在文本编辑器中打开它:
-
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配置就完成了。保存并关闭文件。
使用变量设置文件的优点是它使得重用变得非常简单。复制第一个项目的配置文件以用作第二个配置文件的基础:
-
sudo cp /etc/uwsgi/sites/firstsite.ini /etc/uwsgi/sites/secondsite.ini
使用文本编辑器打开第二个配置文件:
-
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
完成后保存并关闭文件。您的第二个项目现在应该可以开始了。
我们现在拥有了为 Django 项目提供服务所需的配置文件,但我们仍然没有自动化该过程。接下来,我们将创建一个systemd单元文件来管理uWSGIemperor进程并在启动时自动启动uWSGI。
我们将在以下位置创建单元文件/etc/systemd/system
目录,其中保存管理员创建的单元文件。我们将调用我们的文件uwsgi.service
:
-
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 服务。
配置好 uWSGI 并准备就绪后,我们现在可以安装并配置 Nginx 作为我们的反向代理。这可以从 Ubuntu 的默认存储库下载:
-
sudo apt-get install nginx
安装 Nginx 后,我们可以继续为每个项目创建一个服务器块配置文件。通过创建服务器块配置文件从第一个项目开始:
-
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 配置文件的基础。现在复制过来:
-
sudo cp /etc/nginx/sites-available/firstsite /etc/nginx/sites-available/secondsite
在文本编辑器中打开新文件:
-
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
启用它们的目录:
-
sudo ln -s /etc/nginx/sites-available/firstsite /etc/nginx/sites-enabled
-
sudo ln -s /etc/nginx/sites-available/secondsite /etc/nginx/sites-enabled
通过键入以下内容检查配置语法:
如果没有检测到语法错误,您可以重新启动 Nginx 服务以加载新配置:
如果您还记得之前,我们从未真正启动过 uWSGI 服务器。现在输入:
让我们删除要端口的 UFW 规则8080
并允许访问我们的 Nginx 服务器:
-
sudoufw 删除允许8080
-
sudoUFW 允许“Nginx 已满”
您现在应该能够通过访问各自的域名来访问您的两个项目。公共和管理界面都应按预期工作。
如果一切顺利,您可以通过键入以下内容使这两个服务在启动时自动启动:
-
sudo系统控制enable nginx
-
sudo系统控制enable uwsgi
Note
配置 Nginx 后,下一步应该是使用 SSL/TLS 保护服务器的流量。这很重要,因为没有它,所有信息(包括密码)都将以纯文本形式通过网络发送。
如果您有域名,获取 SSL 证书来保护流量的最简单方法是使用 Let’s Encrypt。跟随本指南在 Ubuntu 16.04 上设置 Let’s Encrypt with Nginx。
如果您没有域名,您仍然可以通过以下方式保护您的网站以进行测试和学习:自签名 SSL 证书.
如果您无法访问您的应用程序,则需要对安装进行故障排除。
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
您项目的服务器块中的服务器块必须比要选择的默认服务器块中的服务器块中的服务器块更具体。
502错误表示Nginx无法成功代理请求。许多配置问题都会通过 502 错误来表达,因此需要更多信息才能正确排除故障。
查找更多信息的主要位置是 Nginx 的错误日志。一般来说,这会告诉您代理事件期间哪些条件导致了问题。通过键入以下内容来跟踪 Nginx 错误日志:
-
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
目录,输入:
如果没有socket文件/run/uwsgi
,一般意味着uwsgi
进程无法创建它。检查状态uwsgi
查明是否能够启动的过程:
If the systemctl status
命令表明发生了错误,或者如果在目录中没有找到套接字文件,则表明uWSGI无法正确启动。通过键入以下内容检查 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 进程:
-
sudosystemctl 守护进程重新加载
-
sudosystemctl 重新启动 uwsgi
修复这些问题应该可以让 Nginx 正确找到套接字文件。
connect() 到 unix:/run/uwsgi/firstsite.sock 失败(13:权限被拒绝)
这表明 Nginx 由于权限问题而无法连接到 uWSGI 套接字。通常,当在受限环境中创建套接字或权限错误时,会发生这种情况。虽然uWSGI进程能够创建套接字文件,但Nginx无法访问它。
如果根目录(/
) 套接字文件。通过将套接字文件的绝对路径传递给namei
命令:
- 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-data
group 对套接字本身拥有组所有权。通过这些设置,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 进程以获取更改:
如果你改变uwsgi
systemd 服务文件,重新加载守护进程并通过键入以下内容重新启动进程:
-
sudosystemctl 守护进程重新加载
-
sudosystemctl 重新启动 uwsgi
如果更改 Nginx 服务器块配置,请测试配置,然后输入以下命令测试 Nginx:
-
sudo nginx -t && sudosystemctl 重新启动 nginx
这些命令有助于在您调整配置时获取更改。
在本指南中,我们设置了两个 Django 项目,每个项目都在自己的虚拟环境中。我们已经将 uWSGI 配置为使用为每个项目配置的虚拟环境独立地为每个项目提供服务。之后,我们设置 Nginx 作为反向代理来处理客户端连接并根据客户端请求提供正确的项目。
Django 通过提供许多通用部分使创建项目和应用程序变得简单,使您能够专注于独特的元素。通过利用本文中描述的通用工具链,您可以轻松地为从单个服务器创建的应用程序提供服务。