介绍
Django 是一个强大的 Web 框架,可以帮助您将您的 Python 应用程序或网站从地面上获得。Django 包含一个简化开发服务器来本地测试您的代码,但对于任何与生产有关的内容,需要一个更安全、更强大的 Web 服务器。
在本指南中,我们将展示如何在 Ubuntu 16.04 上安装和配置某些组件以支持和服务 Django 应用程序. 我们将配置 uWSGI 应用程序容器服务器以与我们的应用程序进行交互。
前提和目标
为了完成本指南,您应该有一个新的Ubuntu 16.04服务器实例,具有非根用户的sudo
特权配置,您可以通过我们的 初始服务器设置指南来学习如何设置此设置。
我们将在两个不同的虚拟环境中安装Django,这将允许您的项目和他们的需求单独处理,我们将创建两个样本项目,以便在多项目环境中运行步骤。
一旦我们有我们的应用程序,我们将安装和配置 uWSGI 应用程序服务器. 这将作为我们的应用程序的接口,该接口将使用 HTTP 将客户端请求翻译成我们的应用程序可以处理的 Python 呼叫。
让我们开始吧。
安装和配置 VirtualEnv 和 VirtualEnvWrapper
为了做到这一点,我们将安装virtualenv
,可以创建Python虚拟环境,以及virtualenvwrapper
,为virtualenv
工作流添加一些可用性改进。
我们将使用Python包管理器的pip
来安装这两个组件,我们可以从Ubuntu存储库中安装这个实用程序。
如果您正在使用 Python 2 构建 Django 项目,请输入:
1sudo apt-get update
2sudo apt-get install python-pip
如果您正在使用 Python 3,请键入:
1sudo apt-get update
2sudo apt-get install python3-pip
现在你已经安装了pip
,我们可以在全球范围内安装virtualenv
和virtualenvwrapper
。
如果您正在使用 Python 2,请键入:
1sudo -H pip install --upgrade pip
2sudo -H pip install virtualenv virtualenvwrapper
如果您正在使用 Python 3,请键入:
1sudo -H pip3 install --upgrade pip
2sudo -H pip3 install virtualenv virtualenvwrapper
随着这些组件的安装,我们现在可以配置我们的壳与它需要与virtualenvwrapper
脚本工作的信息。 我们的虚拟环境将被放置在我们的主文件夹中的一个目录中,称为Env
,以便轻松访问。
如果您正在使用 Python 3和pip3
命令,您还需要为您的壳初始化脚本添加一个额外的行:
1echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3" >> ~/.bashrc
無論您正在使用哪個版本的 Python,您需要執行以下命令:
1echo "export WORKON_HOME=~/Env" >> ~/.bashrc
2echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc
现在,源您的壳初始化脚本,以便您可以在当前会话中使用此功能:
1source ~/.bashrc
您现在应该在您的主文件夹中有名为Env
的目录,该目录将包含虚拟环境信息。
创建 Django 项目
现在我们有了虚拟环境工具,我们将创建两个虚拟环境,在每个环境中安装Django,并启动两个项目。
创建第一个项目
我们可以通过使用virtualenvwrapper
脚本为我们提供的一些命令轻松创建虚拟环境。
创建您的第一个虚拟环境,键入您的第一个网站或项目的名称:
1mkvirtualenv firstsite
这将创建一个虚拟环境,在其内部安装Python和pip
,并激活环境。您的提示将改变以表示您现在在新的虚拟环境中运作。它将看起来像这样的东西: (firstsite)user@hostname:~$
. 窗口中的值是您的虚拟环境的名称。通过 pip
安装的任何软件现在将安装在虚拟环境中,而不是在全球系统上。
我们的第一个步骤将是安装Django本身,我们可以用pip
来做到这一点而不使用sudo
,因为我们正在本地在我们的虚拟环境中安装它:
1pip install django
安装了 Django,我们可以通过键入创建我们的第一个样本项目:
1cd ~
2django-admin.py startproject firstsite
在您的主目录中,将创建一个名为firstsite
的目录,其中有一个用于处理项目的不同方面的管理脚本,另一个名为firstsite
的目录则用于容纳实际项目代码。
进入第一级目录,以便我们可以开始为我们的样本项目设置最低要求。
1cd ~/firstsite
首先,您可以迁移数据库以初始化我们项目将使用的 SQLite 数据库. 如果您想要,您可以为您的应用程序设置替代数据库,但这不在本指南的范围内:
1~/firstsite/manage.py migrate
您现在应该在项目目录中有名为「db.sqlite3」的数据库文件,现在我们可以通过键入:
1~/firstsite/manage.py createsuperuser
在此时,您的项目目录(在我们的情况下,~/firstsite
)应该有以下内容:
~/firstsite/manage.py
: 一个 Django 项目管理脚本.~/firstsite/firstsite/
: 该 Django 项目包. 这应该包含__init__.py
,settings.py
,urls.py
和wsgi.py
文件.~/firstsite/db.sqlite3
: 用于存储您的网站信息的 SQLite 数据库文件.
接下来,用文本编辑器打开项目的设置文件:
1nano ~/firstsite/firstsite/settings.py
首先,找出ALLOWED_HOSTS
指令,定义了可以用于连接到Django实例的服务器地址或域名列表,任何未列入此列表的 Host标题的输入请求都会引发例外。
在方块中,列出与您的 Django 服务器相关的 IP 地址或域名。每个项目都应该列入引文中,其中有条纹分开的条目。如果您希望对整个域和任何子域的请求,请预先预设一个时间段,以便开始输入。在下面的片段中,有几个被评论的示例用于示范:
1[label ~/firstsite/firstsite/settings.py]
2. . .
3# The simplest case: just add the domain name(s) and IP addresses of your Django server
4# ALLOWED_HOSTS = [ 'example.com', '203.0.113.5']
5# To respond to 'example.com' and any subdomains, start the domain with a dot
6# ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
7ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . .]
由于我们将设置 Nginx 来服务我们的网站,我们需要配置一个目录,该目录将包含我们的网站的静态资产。这将允许 Nginx 直接服务这些资产,这将对性能产生积极的影响。我们会告诉 Django 将这些内容放入一个名为静态
的目录,在我们的项目的基本目录中。
1[label ~/firstsite/firstsite/settings.py]
2. . .
3STATIC_URL = '/static/'
4STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
当你完成时,保存并关闭文件. 现在,收集我们的站点的静态元素,并通过键入将其放入该目录中:
1~/firstsite/manage.py collectstatic
您可能被要求键入是
以确认操作并收集静态内容. 您的项目目录中将有一个名为静态
的新目录。
接下来,我们可以打开一个端口,以便我们可以访问 Django 开发服务器. 如果您遵循最初的服务器设置指南,您应该有启用 UFW 防火墙。
1sudo ufw allow 8080
有了这一切,我们可以通过暂时启动开发服务器来测试我们的项目。
1~/firstsite/manage.py runserver 0.0.0.0:8080
这将启动开发服务器在端口 8080
. 访问您的服务器的域名或 IP 地址,其次是 8080
在您的浏览器:
1http://server_domain_or_IP:8080
你应该看到一个看起来像这样的页面:
在您的浏览器地址栏中添加/admin
到URL的末尾,您将被带到管理员登录页面:
使用您用createsuperuser
命令选择的管理登录凭证,登录服务器,您将可以访问管理界面:
在测试此功能后,通过在您的终端中键入 CTRL-C来停止开发服务器。
创建第二个项目
第二个项目将以与前一个完全相同的方式创建,我们将在本节中补充解释,看你已经完成了这个过程。
回到您的主目录并为您的新项目创建第二个虚拟环境。
1cd ~
2mkvirtualenv secondsite
3pip install django
新的环境将被创建 and 更改,留下你的以前的虚拟环境. 这个 Django 实例完全与您配置的另一个完全分开。
创建第二个项目并进入项目目录:
1cd ~
2django-admin.py startproject secondsite
3cd ~/secondsite
初始化数据库并创建管理用户:
1~/secondsite/manage.py migrate
2~/secondsite/manage.py createsuperuser
打开设置文件:
1nano ~/secondsite/secondsite/settings.py
将ALLOWED_HOSTS
设置为您第二个项目的域名、服务器的IP地址或两者,就像您在第一个项目中一样:
1ALLOWED_HOSTS = ['second_project_domain_or_IP', 'another_domain_or_IP', . . .]
添加静态文件的位置,就像您在上一个项目中一样:
1[label ~/secondsite/secondsite/settings.py]
2. . .
3STATIC_URL = '/static/'
4STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
保存并关闭文件. 现在,通过键入将静态元素收集到该目录中:
1~/secondsite/manage.py collectstatic
最后,打开开发服务器来测试网站:
1~/secondsite/manage.py runserver 0.0.0.0:8080
您应该检查常规网站在:
1http://server_domain_or_IP:8080
此外,您还可以登录 admin 网站:
1http://server_domain_or_IP:8080/admin
当您确认一切按预期运行时,请在终端中键入 CTRL-C,以停止开发服务器。
退出虚拟环境
由于我们现在已经完成了指南的Django部分,我们可以禁用我们的第二个虚拟环境:
1deactivate
如果您需要在任何一个 Django 站点上再次工作,您应该重新激活相应的环境,您可以使用workon
命令做到这一点:
1workon firstsite
或:
1workon secondsite
再次,在您完成在您的网站上工作时禁用:
1deactivate
现在我们可以继续配置应用程序服务器。
安装 uWSGI 应用服务器
现在我们有两个 Django 项目已经设置并准备好,我们可以配置 uWSGI。 uWSGI 是一个可以通过名为 WSGI 的标准接口与应用程序进行通信的应用程序服务器。
安装UWSGI
与上面链接的指南不同,在本教程中,我们将在全球范围内安装uWSGI,这将导致处理多个Django项目的摩擦减少。在我们安装uWSGI之前,我们需要软件依赖的Python开发文件。
如果您正在使用 Django 與 Python 2,請輸入:
1sudo apt-get install python-dev
如果您正在使用 Python 3,请键入:
1sudo apt-get install python3-dev
现在开发文件已经可用,我们可以通过pip
在全球范围内安装 uWSGI。
如果您正在使用 Python 2,请键入:
1sudo -H pip install uwsgi
如果您正在使用 Python 3,请键入:
1sudo -H pip3 install uwsgi
我們可以快速測試這個應用程式伺服器,通過傳遞給它我們的網站之一的信息,例如,我們可以告訴它服務我們的第一個項目,通過輸入:
1uwsgi --http :8080 --home /home/sammy/Env/firstsite --chdir /home/sammy/firstsite -w firstsite.wsgi
在这里,我们告诉 uWSGI 使用我们位于我们的 ~/Env 目录中的虚拟环境,更改到我们的项目目录,并使用我们内部的
firstsite目录中存储的
wsgi.py文件来服务该文件(使用
firstsite.wsgi` Python 模块语法)。
如果您在浏览器中访问服务器的域名或 IP 地址,其次是 :8080
,您将再次看到您的网站(在 `/admin’ 界面中的静态元素,如 CSS,还不会起作用)。
创建配置文件
从命令行运行 uWSGI 对测试有用,但对于实际部署并不特别有用,相反,我们将在皇帝模式
中运行 uWSGI,这允许主流程自动管理单独的应用程序,因为有一组配置文件。
由于这是一个全球性的过程,我们将创建一个名为/etc/uwsgi/sites
的目录来存储我们的配置文件:
1sudo mkdir -p /etc/uwsgi/sites
在此目录中,我们将放置我们的配置文件. 我们需要为我们服务的每个项目配置文件. uWSGI 过程可以采用各种格式的配置文件,但我们会使用 .ini
文件,因为它们的简单性。
创建您的第一个项目的文件,并在文本编辑器中打开它:
1sudo nano /etc/uwsgi/sites/firstsite.ini
内部,我们必须从[uwsgi]
部分标题开始。我们所有的信息都会在这个标题下进行。我们还将使用变量来使我们的配置文件更加可重复使用。标题后,设置一个名为项目
的变量,以你的第一个项目的名称。添加一个名为uid
的变量,其中包含你的sudo
用户名。
我们还将添加一个名为base
的变量,并将路径添加到您的用户主目录中。这将是我们使用%(variable_name)
语法设置的用户名构建的。
1[label /etc/uwsgi/sites/firstsite.ini]
2[uwsgi]
3project = firstsite
4uid = sammy
5base = /home/%(uid)
接下来,我们需要配置 uWSGI,以便它正确处理我们的项目。我们需要通过设置chdir
选项来更改根项目目录。
通过设置模块,我们可以准确地说明如何与我们的项目进行交互(通过从我们内部项目目录中的 wsgi.py
文件中导入可调用的应用程序
)。
1[label /etc/uwsgi/sites/firstsite.ini]
2[uwsgi]
3project = firstsite
4uid = sammy
5base = /home/%(uid)
6
7chdir = %(base)/%(project)
8home = %(base)/Env/%(project)
9module = %(project).wsgi:application
我们想创建一个5名工人的主流程,我们可以通过添加以下内容来完成:
1[label /etc/uwsgi/sites/firstsite.ini]
2[uwsgi]
3project = firstsite
4uid = sammy
5base = /home/%(uid)
6
7chdir = %(base)/%(project)
8home = %(base)/Env/%(project)
9module = %(project).wsgi:application
10
11master = true
12processes = 5
接下来,我们需要指定 uWSGI 应该如何倾听连接. 在我们的 uWSGI 测试中,我们使用了 HTTP 和网络端口. 然而,由于我们将使用 Nginx 作为反向代理,我们有更好的选择。
由于所有组件都在单一服务器上运行,我们可以使用Unix接口,而不是使用网络端口,这更安全,提供更好的性能。这个接口不会使用HTTP,而是将实施uWSGI的uwsgi
协议,这是一个快速的二进制协议,用于与其他服务器进行通信。
我们还会修改插件的所有权和权限,因为我们会给网页服务器写入访问权限,我们会设置真空
选项,以便在停止服务时自动清除插件文件:
1[label /etc/uwsgi/sites/firstsite.ini]
2[uwsgi]
3project = firstsite
4uid = sammy
5base = /home/%(uid)
6
7chdir = %(base)/%(project)
8home = %(base)/Env/%(project)
9module = %(project).wsgi:application
10
11master = true
12processes = 5
13
14socket = /run/uwsgi/%(project).sock
15chown-socket = %(uid):www-data
16chmod-socket = 660
17vacuum = true
这样,我们的第一个项目的 uWSGI 配置就完成了. 保存并关闭文件。
使用变量设置文件的优点是,它使其非常容易重复使用. 复制您的第一个项目的配置文件以作为您的第二个配置文件的基础:
1sudo cp /etc/uwsgi/sites/firstsite.ini /etc/uwsgi/sites/secondsite.ini
使用您的文本编辑器打开第二个配置文件:
1sudo nano /etc/uwsgi/sites/secondsite.ini
我们只需要在该文件中更改一个值,以便为我们的第二个项目工作。
1[label /etc/uwsgi/sites/secondsite.ini]
2[uwsgi]
3project = secondsite
4uid = sammy
5base = /home/%(uid)
6
7chdir = %(base)/%(project)
8home = %(base)/Env/%(project)
9module = %(project).wsgi:application
10
11master = true
12processes = 5
13
14socket = /run/uwsgi/%(project).sock
15chown-socket = %(uid):www-data
16chmod-socket = 660
17vacuum = true
保存并关闭文件完成后. 您的第二个项目应该准备好现在。
创建 uWSGI 的 systemd 单元文件
我们现在有我们需要服务我们的Django项目的配置文件,但我们还没有自动化这个过程,接下来,我们将创建一个系统d单元文件来管理uWSGI皇帝过程,并自动启动uWSGI。
我们将创建单元文件在 /etc/systemd/system
目录中,在那里存储管理员创建的单元文件。
1sudo nano /etc/systemd/system/uwsgi.service
从[单位]
部分开始,用于指定元数据和订购信息,我们将简单地在这里列出我们的服务的描述:
1[label /etc/systemd/system/uwsgi.service]
2[Unit]
3Description=uWSGI Emperor service
接下来,我们将打开[服务]
部分。我们将使用ExecStartPre
指令来设置我们需要运行我们的服务器的零件。这将确保创建了/run/uwsgi
目录,我们的正常用户将其拥有与www-data
组作为组所有者。与-p
旗帜和chown
命令的mkdir
都成功返回,即使其操作不需要。这就是我们想要的。
对于ExecStart
指令规定的实际启动命令,我们会指向uwsgi
可执行的命令,我们会告诉它在Emperor
模式下运行,允许它使用它在/etc/uwsgi/sites
中找到的文件来管理多个应用程序。
1[label /etc/systemd/system/uwsgi.service]
2[Unit]
3Description=uWSGI Emperor service
4
5[Service]
6ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown sammy:www-data /run/uwsgi'
7ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
8Restart=always
9KillSignal=SIGQUIT
10Type=notify
11NotifyAccess=all
现在,我们所需要做的只是添加[安装]
部分,这使我们能够指定服务何时自动启动,我们将我们的服务与多用户系统状态相关联,每次系统设置为多用户(正常操作状态),我们的服务将被激活:
1[label /etc/systemd/system/uwsgi.service]
2[Unit]
3Description=uWSGI Emperor service
4
5[Service]
6ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown sammy:www-data /run/uwsgi'
7ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
8Restart=always
9KillSignal=SIGQUIT
10Type=notify
11NotifyAccess=all
12
13[Install]
14WantedBy=multi-user.target
完成后,保存并关闭文件。
我们将无法在此时成功启动服务,因为它依赖于www-data
用户的可用性,我们将不得不等待在安装 Nginx 后启动 uWSGI 服务。
安装和配置 Nginx 作为反向代理
有了 uWSGI 配置并做好准备,我们现在可以安装和配置 Nginx 作为我们的反向代理程序,可以从 Ubuntu 的默认存储库下载:
1sudo apt-get install nginx
一旦安装了 Nginx,我们就可以继续为每个项目创建一个服务器块配置文件,从创建一个服务器块配置文件开始:
1sudo nano /etc/nginx/sites-available/firstsite
内部,我们可以通过指明我们的第一个项目应该可访问的端口号和域名来启动我们的服务器块,而server_name
块 must 必须匹配服务器的域名或 IP 地址之一,否则默认的 Nginx 页面可以用来代替。
1[label /etc/nginx/sites-available/firstsite]
2server {
3 listen 80;
4 server_name firstsite.com www.firstsite.com;
5}
接下来,我们可以告诉 Nginx 不要担心如果它找不到一个 favicon. 我们还会将其指向我们收集网站的静态元素的静态文件目录的位置:
1[label /etc/nginx/sites-available/firstsite]
2server {
3 listen 80;
4 server_name firstsite.com www.firstsite.com;
5
6 location = /favicon.ico { access_log off; log_not_found off; }
7 location /static/ {
8 root /home/sammy/firstsite;
9 }
10}
接下来,我们可以创建一个 catch-all 位置块,将所有额外的查询直接传递到我们的应用程序中,我们将包括在 /etc/nginx/uwsgi_params 中发现的
uwsgi` 参数,并将流量传输到 uWSGI 服务器设置的接口:
1[label /etc/nginx/sites-available/firstsite]
2server {
3 listen 80;
4 server_name firstsite.com www.firstsite.com;
5
6 location = /favicon.ico { access_log off; log_not_found off; }
7 location /static/ {
8 root /home/sammy/firstsite;
9 }
10
11 location / {
12 include uwsgi_params;
13 uwsgi_pass unix:/run/uwsgi/firstsite.sock;
14 }
15}
这样,我们的第一个服务器块就完成了。
我们将用此作为我们第二个项目的 Nginx 配置文件的基础。
1sudo cp /etc/nginx/sites-available/firstsite /etc/nginx/sites-available/secondsite
在文本编辑器中打开新文件:
1sudo nano /etc/nginx/sites-available/secondsite
在这里,您将不得不将任何firstsite
的引用更改为secondsite
。您还需要修改server_name
,以便您的第二个项目响应不同的域名,或者如果您没有超过一个域名或IP地址,则需要更改端口。
1[label /etc/nginx/sites-available/secondsite]
2server {
3 listen 80;
4 server_name secondsite.com www.secondsite.com;
5
6 location = /favicon.ico { access_log off; log_not_found off; }
7 location /static/ {
8 root /home/sammy/secondsite;
9 }
10
11 location / {
12 include uwsgi_params;
13 uwsgi_pass unix:/run/uwsgi/secondsite.sock;
14 }
15}
保存并关闭文件,当你完成。
接下来,将您的两个新配置文件链接到 Nginx 的网站启用
目录,以启用它们:
1sudo ln -s /etc/nginx/sites-available/firstsite /etc/nginx/sites-enabled
2sudo ln -s /etc/nginx/sites-available/secondsite /etc/nginx/sites-enabled
通过键入检查配置语法:
1sudo nginx -t
如果没有发现语法错误,您可以重新启动您的 Nginx 服务来加载新的配置:
1sudo systemctl restart nginx
如果你记得从以前,我们从来没有真正启动uWSGI服务器。
1sudo systemctl start uwsgi
让我们删除 UFW 规则到端口 8080
,并允许访问我们的 Nginx 服务器:
1sudo ufw delete allow 8080
2sudo ufw allow 'Nginx Full'
您现在应该能够通过前往各自的域名来接触您的两个项目,公共和行政界面都应该按照预期工作。
如果情况顺利,您可以通过键入两个服务在启动时自动启动:
1sudo systemctl enable nginx
2sudo systemctl enable uwsgi
<$>[注] [标签注] 配置 Nginx 后,下一步应该是使用 SSL/TLS 来确保服务器的流量。
如果您有域名,获取 SSL 证书以保护您的流量最简单的方法是使用 Let's Encrypt. 遵循 此指南在 Ubuntu 16.04 上设置 Let's Encrypt with Nginx。
如果您没有域名,您仍然可以使用自签名的SSL证书(https://andsky.com/tech/tutorials/how-to-create-a-self-signed-ssl-certificate-for-nginx-in-ubuntu-16-04)来保护您的网站进行测试和学习。
解决问题 Nginx 和 uWSGI
如果您无法访问您的应用程序,则需要解决安装问题。
Nginx将显示默认页面而不是Django应用程序
如果 Nginx 显示默认页面而不是向您的应用程序提供代理,这通常意味着您需要在 /etc/nginx/sites-available/firstsite’ 文件中调整
server_name` 以指向您的服务器的 IP 地址或域名。
Nginx 使用server_name
来确定使用哪个服务器块来响应请求. 如果您看到默认的 Nginx 页面,这是一个迹象,表明 Nginx 无法明确匹配请求到一个 sever 块,因此它会返回在/etc/nginx/sites-available/default
中定义的默认块。
项目服务器块中的server_name
必须比要选择的默认服务器块中的server_name
更为具体。
Nginx 顯示 502 Bad Gateway 錯誤,而不是 Django 應用程式
502 错误表明 Nginx 无法成功代理请求. 各种配置问题以 502 错误表达,因此需要更多信息才能正确解决问题。
寻找更多信息的主要场所是在 Nginx 的错误日志中。 一般来说,这会告诉您在代理事件期间引起的问题的条件。
1sudo tail -F /var/log/nginx/error.log
现在,请在浏览器中提出另一个请求,以生成新错误(尝试刷新页面)。
你可能会看到以下的一些信息:
connect() 到 unix:/run/uwsgi/firstsite.sock 失败了(2:没有此类文件或目录)
這表明 Nginx 無法在該位置找到插件檔案,您應該將在「/etc/nginx/sites-available」檔案中的「firstsite」和「secondsite.sock」檔案中定義的「uwsgi_pass」位置與在「/run/uwsgi」目錄中的「firstsite.sock」和「secondsite.sock」插件檔案的實際位置進行比較。
在 /run/uwsgi
目录中检查插件文件的存在,键入:
1sudo ls /run/uwsgi
如果在/run/uwsgi
中没有插件文件,这通常意味着uwsgi
过程无法创建它。
1sudo systemctl status uwsgi
如果systemctl status
命令显示出现错误,或者您在目录中找不到插件文件,则表明 uWSGI 无法正确启动。
1sudo journalctl -u uwsgi
请查看日志中的消息,了解 uWSGI 遇到问题的地方. 您可能遇到问题的原因有很多,但如果 uWSGI 无法创建插件文件,这是由于以下原因之一:
项目文件由根
用户拥有,而不是sudo
用户
*ExecStartPre
行在/etc/systemd/system/uwsgi.service
文件中不包含创建目录并分配所有权的正确命令
*uwsgi_pass
路径在/etc/gi/sites
目录中的网站配置文件中不正确。检查下列项目:
chdir
指向主要项目目录的正确位置。- 在
ini
目录中定义的uWSGI配置不正确。
如果您对 /etc/systemd/system/uwsgi.service
文件进行更改,请重新加载 DAEMON 来重新读取服务定义,然后通过键入:
1sudo systemctl daemon-reload
2sudo systemctl restart uwsgi
修复这些问题应该允许 Nginx 正确找到插件文件。
connect() 到 unix:/run/uwsgi/firstsite.sock 失败了(13:允许被拒绝)
这表明 Nginx 由于权限问题无法连接到 uWSGI 接口. 通常情况下,当接口在受限制的环境中创建或权限错误时,会发生这种情况。
这种情况可能发生,如果在 root 目录 (/
) 和 socket 文件之间有有限的权限,我们可以通过将我们的 socket 文件的绝对路径传递到 `namei' 命令来查看 socket 文件及其每个母目录的权限和所有权值:
1namei -nom /run/uwsgi/firstsite.sock
1[secondary_label Output]
2f: /run/uwsgi/firstsite.sock
3 drwxr-xr-x root root /
4 drwxr-xr-x root root run
5 drwxr-xr-x sammy www-data uwsgi
6 srw-rw---- sammy www-data firstsite.sock
输出显示了每个目录组件的权限. 通过查看权限(第一列),所有者(第二列)和组所有者(第三列),我们可以确定接口文件的访问类型是允许的。
在上面的示例中,导致插件文件的每个目录都有世界读取和执行权限(这些目录的权限列以r-x
而不是---
结束)。
如果导致插槽的任何目录都不是由www-data
组所有,或者没有世界阅读和执行权限, Nginx 将无法访问插槽,这通常意味着配置文件有错误。
如果目录路径过于限制权限或所有权,请查看 /etc/systemd/system/uwsgi.service
文件。 ExecStartPre
指令负责创建 /run/uwsgi
目录并将组所有权分配给 www-data
组。
如果插件文件本身无法访问 Nginx 进程,则在 /etc/uwsgi/sites 中的
.ini` 文件中定义的设置可能不正确。
进一步麻烦解决
为了进一步解决问题,日志可以帮助缩小根源原因,反过来检查每个原因,并寻找指示问题区域的消息。
以下日志可能有用:
- 检查 Nginx 进程日志,输入:
sudo journalctl -u nginx
- 检查 Nginx 访问日志,输入:
sudo less /var/log/nginx/access.log
- 检查 Nginx 错误日志,输入:
sudo less /var/log/nginx/error.log
- 检查 uWSGI 应用日志,输入:
sudo journalctl - uwsgi
当您更新配置或应用程序时,您可能需要重新启动流程以适应您的更改。
如果您更新 Django 应用程序,您可以通过键入重新启动 uWSGI 流程来获取更改:
1sudo systemctl restart uwsgi
如果您更改了uwsgi
systemd 服务文件,请重新加载 DAEMON 并通过键入重新启动过程:
1sudo systemctl daemon-reload
2sudo systemctl restart uwsgi
如果您更改了 Nginx 服务器块配置,请测试配置,然后通过键入 Nginx:
1sudo nginx -t && sudo systemctl restart nginx
这些命令有助于在调整配置时获取更改。
结论
在本指南中,我们已经设置了两个Django项目,每个在自己的虚拟环境中。我们已经配置了uWSGI来独立使用每个项目配置的虚拟环境来服务每个项目。
Django 通过提供许多常见元素来简化项目和应用程序的创建,使您能够专注于独特的元素,通过利用本文中描述的通用工具链,您可以轻松地从单一服务器中服务您创建的应用程序。