介绍
Django是一个功能强大的Web框架,可以帮助您将Python应用程序或网站打开。Django包含一个简化的开发服务器,用于在本地测试您的代码,但对于与生产相关的任何事情,都需要更安全,更强大的Web服务器。
在本指南中,我们将演示如何在Ubuntu 16.04上安装和配置一些组件以支持和服务Django应用程序。我们将配置uWSGI应用程序容器服务器以与我们的应用程序进行交互。然后,我们将设置Nginx来反向代理uWSGI,使我们能够访问其安全和性能功能来为我们的应用程序提供服务。
先决条件和目标
为了完成本指南,您应该有一个新的Ubuntu 16.04服务器实例,并且sudo
配置了具有特权的非root用户。您可以通过运行我们的初始服务器设置指南来了解如何进行设置。
我们将在两个不同的虚拟环境中安装Django。这将允许您的项目和他们的要求分开处理。我们将创建两个示例项目,以便我们可以贯穿多项目环境中的步骤。
一旦我们有我们的应用程序,我们将安装和配置uWSGI应用程序服务器。这将作为我们应用程序的接口,它将使用HTTP将客户端请求转换为我们的应用程序可以处理的Python调用。然后,我们将在uWSGI之前设置Nginx,以利用其高性能连接处理机制和易于实现的安全功能。
让我们开始吧。
安装并配置VirtualEnv和VirtualEnvWrapper
我们将在他们自己的虚拟环境中安装我们的Django项目,以隔离每个项目的需求。为此,我们将进行安装virtualenv
,它可以创建Python虚拟环境,并virtualenvwrapper
为virtualenv
工作流程增加一些可用性改进。
我们将使用pip
Python包管理器来安装这两个组件。我们可以从Ubuntu存储库安装这个实用程序。
如果您使用Python 2构建您的Django项目,请键入:
- sudo apt-get update
- sudo apt-get install python-pip
如果您使用的是Python 3,请输入:
- sudo apt-get update
- sudo apt-get install python3-pip
现在你已经pip
安装好了,我们可以安装virtualenv
并virtualenvwrapper
全球化。我们也将pip
使用pip
它自己升级到最新版本。
如果您使用的是Python 2,请输入:
- sudo -H pip install --upgrade pip
- sudo -H pip install virtualenv virtualenvwrapper
如果您使用的是Python 3,请输入:
- sudo -H pip3 install --upgrade pip
- sudo -H pip3 install virtualenv virtualenvwrapper
安装这些组件后,我们现在可以配置我们的shell所需的信息来处理virtualenvwrapper
脚本。我们的虚拟环境将全部放置在我们主文件夹中的一个目录中,Env
以方便访问。这是通过一个称为的环境变量来配置的WORKON_HOME
。我们可以将它添加到我们的shell初始化脚本中,并可以获取虚拟环境包装脚本。
如果您使用的是Python 3和该pip3
命令,则还需要在shell初始化脚本中添加一行:
- echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3" >> ~/.bashrc
无论您使用的是哪个版本的Python,都需要运行以下命令:
- echo "export WORKON_HOME=~/Env" >> ~/.bashrc
- echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc
现在,获取您的shell初始化脚本,以便您可以在当前会话中使用此功能:
- source ~/.bashrc
您现在应该Env
在您的主文件夹中调用目录,该目录将保存虚拟环境信息。
创建Django项目
现在我们有了虚拟环境工具,我们将创建两个虚拟环境,分别安装Django,并启动两个项目。
创建第一个项目
通过使用virtualenvwrapper
脚本提供给我们的一些命令,我们可以轻松创建虚拟环境。
输入以下命令,创建您的第一个虚拟环境,其中包含您的第一个站点或项目
- mkvirtualenv firstsite
这将创建一个虚拟环境,安装Python并pip
在其中,并激活环境。您的提示将更改为表明您现在正在新虚拟环境中运行。它看起来像这样:。括号中的值是您的虚拟环境的名称。现在安装的任何软件都将安装到虚拟环境中,而不是安装在全局系统上。这使我们能够以每个项目为基础隔离我们的软件包。(firstsite)user@hostname:~$
pip
我们的第一步将是安装Django本身。我们可以使用pip
它,sudo
因为我们在我们的虚拟环境中本地安装:
- pip install django
安装Django后,我们可以通过键入以下命令创建我们的第一个示例项目:
- cd ~
- django-admin.py startproject firstsite
这将创建一个firstsite
在您的主目录中调用的目录。其中包括用于处理项目各个方面的管理脚本,以及用于存放实际项目代码的另一个同名目录。
进入第一级目录,以便我们可以开始设置示例项目的最低要求。
- cd ~/firstsite
首先迁移数据库以初始化我们的项目将使用的SQLite数据库。如果您愿意,您可以为您的应用程序设置一个替代数据库,但这不在本指南的范围之内:
- ~/firstsite/manage.py migrate
您现在应该db.sqlite3
在项目目录中调用一个数据库文件。现在,我们可以通过输入以下命令来创建管理用户
- ~/firstsite/manage.py createsuperuser
此时,您的项目目录(在我们的例子中)应该有以下内容:~/firstsite
~/firstsite/manage.py
:一个Django项目管理脚本。~/firstsite/firstsite/
:Django项目包。这应该包括__init__.py
,settings.py
,urls.py
,和wsgi.py
文件。~/firstsite/db.sqlite3
:用于存储站点信息的SQLite数据库文件。
接下来,使用文本编辑器打开项目的设置文件:
- nano ~/firstsite/firstsite/settings.py
从查找ALLOWED_HOSTS
指令开始。这定义了可用于连接到Django实例的服务器地址或域名列表。具有不在此列表中的主机头的任何传入请求都会引发异常。Django要求你设置这个以防止某种类型的安全漏洞。
在方括号中,列出与您的Django服务器关联的IP地址或域名。每个项目应用引号括起来,并用逗号分隔。如果您希望请求整个域名和任何子域名,请在条目的开头添加一段时间。在下面的代码片段中,有几个用于演示的注释示例:
. . .
# 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
我们项目的基本目录中调用的目录中。将此行添加到文件的底部以配置此行为:
. . .
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
完成后保存并关闭文件。现在,收集我们网站的静态元素,并通过输入以下内容将它们放入该目录中:
- ~/firstsite/manage.py collectstatic
您可能会被要求键入“是”来确认操作并收集静态内容。static
在你的项目目录中会有一个新的目录。
接下来,我们可以打开一个端口,以便我们可以访问Django开发服务器。如果您遵循最初的服务器设置指南,则应启用UFW防火墙。键入以下命令允许连接到端口8080:
- sudo ufw allow 8080
除此之外,我们可以通过暂时启动开发服务器来测试我们的项目。类型:
- ~/firstsite/manage.py runserver 0.0.0.0:8080
这将启动端口上的开发服务器8080
。访问您的服务器的域名或IP地址,然后8080
在浏览器中查看:
http://server_domain_or_IP:8080
你应该看到一个看起来像这样的页面:
/admin
在浏览器的地址栏中添加到网址的末尾,然后转到管理员登录页面:
使用通过该createsuperuser
命令选择的管理登录凭证,登录到服务器。您将可以访问管理界面:
在测试完此功能之后,通过在终端中输入CTRL-C来停止开发服务器。我们现在可以继续进行我们的第二个项目。
创建第二个项目
第二个项目的创建方式与第一个项目完全相同。我们将在本节中略去解释,看看你已经完成了一次。
移回您的主目录并为您的新项目创建第二个虚拟环境。激活后在这个新环境中安装Django:
- cd ~
- mkvirtualenv secondsite
- pip install django
新环境将被创建并更改为,留下以前的虚拟环境。这个Django实例完全独立于你配置的另一个实例。这使您可以独立管理它们并根据需要进行自定义。
创建第二个项目并进入项目目录:
- cd ~
- django-admin.py startproject secondsite
- cd ~/secondsite
初始化数据库并创建一个管理用户:
- ~/secondsite/manage.py migrate
- ~/secondsite/manage.py createsuperuser
打开设置文件:
- nano ~/secondsite/secondsite/settings.py
将ALLOWED_HOSTS
您的第二个项目的域名,服务器的IP地址或两者一起设置,就像您对第一个项目所做的一样:
ALLOWED_HOSTS = ['second_project_domain_or_IP', 'another_domain_or_IP', . . .]
添加静态文件的位置,就像您在之前的项目中一样:
. . .
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部分,因此我们可以停用第二个虚拟环境:
- deactivate
如果您需要再次在任一Django网站上工作,则应重新激活各自的环境。您可以使用以下workon
命令来完成此操作:
- workon firstsite
要么:
- workon secondsite
再次,当你完成你的网站时停用:
- deactivate
我们现在可以继续配置应用程序服务器。
设置uWSGI应用程序服务器
现在我们有两个Django项目已经准备就绪,我们可以配置uWSGI。uWSGI是一个应用程序服务器,可以通过名为WSGI的标准接口与应用程序通信。要了解更多信息,请阅读我们关于在Ubuntu 14.04上设置uWSGI和Nginx的指南的这一部分。
安装uWSGI
与上面链接的指南不同,在本教程中,我们将在全球范围内安装uWSGI。这会在处理多个Django项目时产生较小的摩擦。在我们安装uWSGI之前,我们需要软件依赖的Python开发文件。我们可以直接从Ubuntu的仓库安装。
如果您在Python 2中使用Django ,请输入:
- sudo apt-get install python-dev
如果您使用的是Python 3,请输入:
- sudo apt-get install python3-dev
既然开发文件可用,我们可以通过全局安装uWSGI pip
。
如果您使用的是Python 2,请输入:
- sudo -H pip install uwsgi
如果您使用的是Python 3,请输入:
- sudo -H pip3 install uwsgi
我们可以通过向我们的某个网站传递信息来快速测试此应用程序服务器。例如,我们可以通过输入以下内容来告诉它为我们的第一个项目服务:
- uwsgi --http :8080 --home /home/sammy/Env/firstsite --chdir /home/sammy/firstsite -w firstsite.wsgi
在这里,我们告诉uWSGI使用位于我们~/Env
目录中的虚拟环境,转到我们项目的目录,并使用wsgi.py
存储在内部firstsite
目录中的文件来为文件提供服务(使用firstsite.wsgi
Python模块语法)。对于我们的演示,我们告诉它在端口上提供HTTP服务8080
。
如果您在浏览器中访问服务器的域名或IP地址,然后:8080
再次看到您的站点(/admin
接口中的静态元素(如CSS)将无法工作)。完成此功能测试后,在终端中键入CTRL-C。
创建配置文件
从命令行运行uWSGI对测试非常有用,但对于实际部署并不特别有用。相反,我们将以“Emperor模式”运行uWSGI,它允许主进程在给定一组配置文件的情况下自动管理单独的应用程序。
创建一个将保存配置文件的目录。由于这是一个全局过程,因此我们将创建一个目录/etc/uwsgi/sites
来存储我们的配置文件:
- sudo mkdir -p /etc/uwsgi/sites
在这个目录中,我们将放置我们的配置文件。我们需要为我们正在服务的每个项目提供配置文件。uWSGI进程可以采用各种格式的配置文件,但.ini
由于其简单性,我们将使用文件。
为您的第一个项目创建一个文件并在文本编辑器中打开它:
- sudo nano /etc/uwsgi/sites/firstsite.ini
在里面,我们必须从[uwsgi]
部分标题开始。我们所有的信息将在这个标题下。我们也将使用变量来使我们的配置文件更加可重用。在标题后面,设置一个名为project
第一个项目的变量。添加一个名为uid
哪个变量来保存您的sudo
用户名
我们还将添加一个变量base
,并将其路径添加到用户的主目录中。这将使用我们使用%(variable_name)
语法设置的用户名来构造。当配置被读取时,这将被变量的值替换:
[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)
接下来,我们需要配置uWSGI,以便正确处理我们的项目。我们需要通过设置chdir
选项来切换到根项目目录。我们可以使用相同的变量语法来组合主目录和项目名称。
以类似的方式,我们将为我们的项目指出虚拟环境。通过设置模块,我们可以准确地指出如何与我们的项目进行交互(通过从wsgi.py
我们内部项目目录中的文件中导入可调用的“应用程序” )。这些项目的配置将如下所示:
[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)
chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
我们想要创建一个拥有5名工人的主流程。我们可以通过添加这个来做到这一点
[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,而是实现uWSGI的uwsgi
协议,这是一个用于与其他服务器通信的快速二进制协议。Nginx可以使用uwsgi
协议本地代理,所以这是我们的最佳选择。
我们还将修改套接字的所有权和权限,因为我们将授予Web服务器写入权限。我们将设置该vacuum
选项,以便在服务停止时自动清除套接字文件:
[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
使用您用于第二个项目的名称修改变量:
[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单元文件来管理uWSGI emperor进程,并在启动时自动启动uWSGI。
我们将在/etc/systemd/system
保存管理员创建的单元文件的目录中创建单元文件。我们将调用我们的文件uwsgi.service
:
- sudo nano /etc/systemd/system/uwsgi.service
从[Unit]
用于指定元数据和订购信息的部分开始。我们将在此简单介绍我们的服务:
[Unit]
Description=uWSGI Emperor service
接下来,我们将打开该[Service]
部分。我们将使用该ExecStartPre
指令来设置我们运行我们的服务器所需的部分。这将确保/run/uwsgi
目录已创建,并且我们的普通用户拥有该目录并将该www-data
组作为组所有者。无论mkdir
用-p
标志和chown
命令成功返回即使不需要他们的操作。这是我们想要的。
对于由ExecStart
指令指定的实际启动命令,我们将指向uwsgi
可执行文件。我们会告诉它以“Emperor模式”运行,允许它使用它找到的文件来管理多个应用程序/etc/uwsgi/sites
。我们还将添加systemd正确管理过程所需的部分。这些取自这里的uWSGI文档。
[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]
部分。这使我们能够指定服务何时应该自动启动。我们将把我们的服务与多用户系统状态联系起来。无论何时为多个用户设置系统(正常操作条件),我们的服务将被激活:
[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的默认存储库下载:
- sudo apt-get install nginx
一旦安装了Nginx,我们可以继续为每个项目创建一个服务器块配置文件。从第一个项目开始,创建一个服务器块配置文件:
- sudo nano /etc/nginx/sites-available/firstsite
在内部,我们可以通过指出我们的第一个项目应该可访问的端口号和域名来启动我们的服务器块。该server_name
块必须匹配其中一个服务器的域名或IP地址,否则可以使用默认的Nginx页面。我们假设您有每个域名:
server {
listen 80;
server_name firstsite.com www.firstsite.com;
}
接下来,我们可以告诉Nginx如果找不到favicon,不要担心。我们还会将它指向我们收集站点静态元素的静态文件目录的位置:
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服务器设置的套接字中uwsgi
找到的参数/etc/nginx/uwsgi_params
并将其传递到该套接字:
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
在这里,你必须改变任何引用来firstsite
引用secondsite
。server_name
如果您没有多个域名或IP地址,您还需要修改以便第二个项目响应不同的域名或更改端口。当你完成后,它会看起来像这样:
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
输入以下命令来检查配置语法:
- sudo nginx -t
如果未检测到语法错误,则可以重新启动Nginx服务以加载新配置:
- sudo systemctl restart nginx
如果您从前面记得,我们从未真正启动过uWSGI服务器。现在通过键入:
- sudo systemctl start uwsgi
让我们删除UFW规则来移植,8080
并允许访问我们的Nginx服务器:
- sudo ufw delete allow 8080
- sudo ufw allow 'Nginx Full'
您现在应该可以通过转到各自的域名来访问您的两个项目。公共和管理界面都应按预期工作。
如果这一切顺利,您可以通过输入以下命令启用两项服务:
- sudo systemctl enable nginx
- sudo systemctl enable uwsgi
配置Nginx后,下一步应该是使用SSL / TLS将流量保护到服务器。这很重要,因为没有它,所有信息(包括密码)都将以纯文本的形式通过网络发送。
如果您有域名,获取SSL证书以保护您的流量的最简单方法是使用Let's Encrypt。按照本指南设置让我们在Ubuntu 16.04上使用Nginx加密。
如果您没有域名,您仍然可以使用自签名SSL证书保护您的网站进行测试和学习。
排除Nginx和uWSGI的故障
如果您无法访问您的应用程序,则需要对您的安装进行故障排除。
Nginx显示默认页面而不是Django应用程序
如果Nginx显示默认页面而不是代理应用程序,它通常意味着您需要调整文件server_name
内的指向您的服务器的IP地址或域名。/etc/nginx/sites-available/firstsite
Nginx使用它server_name
来确定使用哪个服务器块来响应请求。如果您看到默认的Nginx页面,则表示Nginx无法将请求显式匹配到服务器块,因此它将回退到在中定义的默认块/etc/nginx/sites-available/default
。
在server_name
您的项目中的服务器块必须更加具体的,而不是被选择一个默认的服务器模块。
Nginx显示502错误的网关错误,而不是Django应用程序
502错误表示Nginx无法成功代理请求。各种各样的配置问题都以502错误表达,因此需要更多信息才能正确排除故障。
查找更多信息的主要位置在Nginx的错误日志中。一般来说,这会告诉你在代理事件期间哪些情况会导致问题。输入以下命令来跟踪Nginx错误日志:
- sudo tail -F /var/log/nginx/error.log
现在,在浏览器中发出另一个请求以生成新的错误(尝试刷新页面)。您应该看到写入日志的新错误消息。如果你看看这个信息,它应该可以帮助你缩小问题的范围。
您可能会看到以下一些消息:
连接()到unix:/run/uwsgi/firstsite.sock失败(2:没有这样的文件或目录)
这表明Nginx无法在给定位置找到套接字文件。您应该将文件和文件中uwsgi_pass
定义的位置firstsite
与secondsite
目录中/etc/nginx/sites-available
的firstsite.sock
和secondsite.sock
套接字文件的实际位置进行比较/run/uwsgi
。
/run/uwsgi
通过输入以下内容来检查目录中是否存在套接字文件:
- sudo ls /run/uwsgi
如果没有套接字文件/run/uwsgi
,通常意味着该uwsgi
进程无法创建它。检查uwsgi
进程的状态以确定它是否能够启动:
- sudo systemctl status uwsgi
如果该systemctl status
命令指示发生错误,或者如果在目录中找不到套接字文件,则表示uWSGI无法正确启动。输入以下命令以检查uWSGI进程日志:
- sudo journalctl -u uwsgi
查看日志中的消息,找出uWSGI遇到问题的位置。有很多原因可能会遇到问题,但通常,如果uWSGI无法创建套接字文件,则会出于以下原因之一:
- 项目文件由
root
用户而不是sudo
用户拥有 - 该文件中的
ExecStartPre
行/etc/systemd/system/uwsgi.service
不包含用于创建目录和分配所有权的正确命令 - 将
uwsgi_pass
在该网站的配置文件路径/etc/nginx/sites-available
目录的目的不是正确的插槽位置 .ini
在/etc/uwsgi/sites
目录中的文件中定义的uWSGI配置不正确。检查以下项目:- 该
chdir
指令一旦插入,就指向主项目目录。 - 该
home
指令一旦插入,指向虚拟环境目录。 - 该
module
指令使用Python模块导入语法wsgi.py
从内部项目目录中加载文件。 - 该
socket
指令指向文件中的一个/run/uwsgi
文件(应该通过ExecStartPre
上述服务文件中的行创建)。
- 该
如果对/etc/systemd/system/uwsgi.service
文件进行了更改,请重新加载守护程序以重新读取服务定义,然后键入以下命令重新启动uWSGI进程:
- sudo systemctl daemon-reload
- sudo systemctl restart uwsgi
解决这些问题应该允许Nginx正确地找到套接字文件。
connect()unix:/run/uwsgi/firstsite.sock失败(13:权限被拒绝)
这表明由于权限问题,Nginx无法连接到uWSGI套接字。通常,这是在套接字在受限环境中创建或权限错误时发生的。虽然uWSGI进程能够创建套接字文件,但Nginx无法访问它。
如果在根目录(/
)和套接字文件之间的任何点上的权限有限,就会发生这种情况。我们可以通过将绝对路径传递给我们的套接字文件来查看套接字文件及其每个父目录的权限和所有权值namei
:
- namei -nom /run/uwsgi/firstsite.sock
输出显示每个目录组件的权限。通过查看权限(第一列),所有者(第二列)和组所有者(第三列),我们可以找出套接字文件允许的访问类型。
在上面的示例中,导向到套接字文件的每个目录都具有世界读取和执行权限(目录的权限列以结束r-x
而不是---
)结束。该www-data
组拥有套接字本身的组所有权。通过这些设置,Nginx进程应该能够成功访问套接字。
如果任何通向套接字的目录不属于该www-data
组,或者没有世界读取和执行权限,Nginx将无法访问该套接字。通常,这意味着配置文件有错误。
如果目录路径的权限或所有权过于严格,请查看该/etc/systemd/system/uwsgi.service
文件。该ExecStartPre
指令负责创建/run/uwsgi
目录并将组所有权分配给www-data
组。如果这里的命令不正确,那么目录路径可能太严格了。
如果套接字文件本身对Nginx进程不可访问,则.ini
文件中定义的设置/etc/uwsgi/sites
可能不正确。检查值chown-socket
并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进程来输入以下内容来选择更改:
- sudo systemctl restart uwsgi
如果更改uwsgi
systemd服务文件,请重新加载守护程序并键入以下命令重新启动进程:
- sudo systemctl daemon-reload
- sudo systemctl restart uwsgi
如果您更改了Nginx服务器块配置,请通过键入以下命令来测试配置,然后测试Nginx:
- sudo nginx -t && sudo systemctl restart nginx
这些命令有助于在调整配置时获取更改。
结论
在本指南中,我们已经设置了两个Django项目,每个项目都在自己的虚拟环境中。我们已将uWSGI配置为使用为每个项目配置的虚拟环境独立提供每个项目。之后,我们将Nginx设置为反向代理来处理客户端连接,并根据客户端请求提供正确的项目。
Django通过提供许多常用的部分使得创建项目和应用程序变得简单,让您专注于独特的元素。通过利用本文中介绍的通用工具链,您可以轻松地为从单个服务器创建的应用程序提供服务。