如何在 CentOS 7 上使用 uWSGI 和 Nginx 服务 Django 应用程序

介绍

Django 是一个强大的 Web 框架,可以帮助您将您的 Python 应用程序或网站从地面上获得。Django 包含一个简化开发服务器来本地测试您的代码,但对于任何与生产有关的内容,需要一个更安全、更强大的 Web 服务器。

在本指南中,我们将展示如何在 CentOS 7 上安装和配置某些组件以支持和服务 Django 应用程序. 我们将配置 uWSGI 应用程序容器服务器以与我们的应用程序进行交互。

前提和目标

要完成本指南,您应该有一个新的 CentOS 7 服务器实例,具有配置了sudo权限的非根用户,您可以通过我们的 初始服务器设置指南来学习如何设置此设置。

我们将在两个不同的虚拟环境中安装Django,这将允许您的项目和他们的需求单独处理,我们将创建两个样本项目,以便在多项目环境中运行步骤。

一旦我们有我们的应用程序,我们将安装和配置 uWSGI 应用程序服务器. 这将作为我们的应用程序的接口,该接口将使用 HTTP 将客户端请求翻译成我们的应用程序可以处理的 Python 呼叫。

让我们开始吧。

安装和配置 VirtualEnv 和 VirtualEnvWrapper

为了做到这一点,我们将安装virtualenv,可以创建Python虚拟环境,以及virtualenvwrapper,为virtualenv工作流添加一些可用性改进。

我们将使用Python包管理器的pip来安装这两个组件,要获取pip,我们首先需要启用EPEL存储库。

1sudo yum install epel-release

一旦启用了EPEL,我们可以通过键入以下方式安装pip:

1sudo yum install python-pip

现在你已经安装了pip,我们可以通过键入全球安装virtualenvvirtualenvwrapper:

1sudo pip install virtualenv virtualenvwrapper

随着这些组件的安装,我们现在可以配置我们的壳与它需要与virtualenvwrapper脚本工作的信息。 我们的虚拟环境将被放置在我们的主文件夹中的一个目录中,称为Env,以便轻松访问。

要将相应的行添加到您的壳初始化脚本中,您需要运行以下命令:

1echo "export WORKON_HOME=~/Env" >> ~/.bashrc
2echo "source /usr/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./manage.py migrate

您现在应该在项目目录中有名为「db.sqlite3」的数据库文件,现在我们可以通过键入:

1./manage.py createsuperuser

您将需要选择用户名,提供联系人电子邮件地址,然后选择并确认密码。

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

1nano firstsite/settings.py

由于我们将设置 Nginx 来服务我们的网站,我们需要配置一个目录,该目录将包含我们的网站的静态资产。这将允许 Nginx 直接服务这些资产,这将对性能产生积极的影响。我们会告诉 Django 将这些内容放入一个名为静态的目录,在我们的项目的基本目录中。

1STATIC_ROOT = os.path.join(BASE_DIR, "static/")

当你完成时,保存并关闭文件. 现在,收集我们的站点的静态元素,并通过键入将其放入该目录中:

1./manage.py collectstatic

您可以输入来确认操作并收集静态内容. 您的项目目录中将有一个名为静态的新目录。

有了这一切,我们可以通过暂时启动开发服务器来测试我们的项目。

1./manage.py runserver 0.0.0.0:8080

这将启动开发服务器在端口 8080. 访问您的服务器的域名或 IP 地址,其次是 8080 在您的浏览器:

1http://server_domain_or_IP:8080

你应该看到一个看起来像这样的页面:

Django sample site

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

Django admin login

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

Django admin interface

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

创建第二个项目

第二个项目将以与前一个完全相同的方式创建,我们将在本节中补充解释,看你已经完成了这个过程。

回到您的主目录并为您的新项目创建第二个虚拟环境。

1cd ~
2mkvirtualenv secondsite
3pip install django

新的环境将被创建 and 更改,留下你的以前的虚拟环境. 这个 Django 实例完全与您配置的另一个完全分开。

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

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

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

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

打开设置文件:

1nano secondsite/settings.py

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

1STATIC_ROOT = os.path.join(BASE_DIR, "static/")

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

1./manage.py collectstatic

最后,打开开发服务器来测试网站:

1./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开发文件。

1sudo yum install python-devel gcc

现在开发文件已经可用,我们可以通过键入pip在全球范围内安装uWSGI:

1sudo pip install uwsgi

我們可以快速測試這個應用程式伺服器,通過傳遞給它我們的網站之一的信息,例如,我們可以告訴它服務我們的第一個項目,通過輸入:

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

在这里,我们告诉uWSGI使用我们位于我们的~/Env目录中的虚拟环境,更改到我们的项目目录,并使用存储在我们内部firstsite目录中的wsgi.py文件来服务该文件. 为了我们的演示,我们告诉它在端口8080上服务HTTP。 如果您在浏览器中访问服务器的域名或IP地址,然后是:8080,您将再次看到您的网站(在/admin界面中的静态元素还不会起作用)。

创建配置文件

从命令行运行 uWSGI 对测试有用,但对于实际部署并不特别有用,相反,我们将在皇帝模式中运行 uWSGI,这允许主流程自动管理单独的应用程序,因为有一组配置文件。

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

1sudo mkdir -p /etc/uwsgi/sites
2cd /etc/uwsgi/sites

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

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

1sudo nano firstsite.ini

内部,我们必须从[uwsgi]部分标题开始。我们所有的信息都会在这个标题下进行。我们还将使用变量来使我们的配置文件更加可重复使用。标题后,设置一个名为项目的变量,以您的第一个项目的名称。 设置另一个变量,以您的正常用户名为项目文件的所有者。 添加一个名为base的变量,该变量使用您的用户名来建立您的用户主目录的路径:

1[uwsgi]
2project = firstsite
3username = user
4base = /home/%(username)

接下来,我们需要配置 uWSGI,以便它正确处理我们的项目。我们需要通过设置chdir选项来更改根项目目录。我们可以通过使用%(variable_name)语法将先前设置的首页目录和项目名称设置相结合。

通过设置模块,我们可以准确地说明如何与我们的项目进行交互(通过从我们项目目录中的 wsgi.py 文件中导入可调用的应用程序)。

1[uwsgi]
2project = firstsite
3username = user
4base = /home/%(username)
5
6chdir = %(base)/%(project)
7home = %(base)/Env/%(project)
8module = %(project).wsgi:application

我们想创建一个5名工人的主流程,我们可以通过添加以下内容来完成:

 1[uwsgi]
 2project = firstsite
 3username = user
 4base = /home/%(username)
 5
 6chdir = %(base)/%(project)
 7home = %(base)/Env/%(project)
 8module = %(project).wsgi:application
 9
10master = true
11processes = 5

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

由于所有组件都在单一服务器上运行,我们可以使用Unix接口,而不是使用网络端口,这更安全,提供更好的性能。这个接口不会使用HTTP,而是将实施uWSGI的uwsgi协议,这是一个快速的二进制协议,旨在与其他服务器进行通信。

我们还将修改插件的权限和所有权,因为我们将给网页服务器写入访问权限。 插件本身将放置在/run/uwsgi目录中(我们将创建这个目录在一小块)在那里 uWSGI 和 Nginx 都可以访问它。

 1[uwsgi]
 2project = firstsite
 3username = user
 4base = /home/%(username)
 5
 6chdir = %(base)/%(project)
 7home = %(base)/Env/%(project)
 8module = %(project).wsgi:application
 9
10master = true
11processes = 5
12
13uid = %(username)
14socket = /run/uwsgi/%(project).sock
15chown-socket = %(username):nginx
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[uwsgi]
 2project = firstsite
 3username = user
 4base = /home/%(username)
 5
 6chdir = %(base)/%(project)
 7home = %(base)/Env/%(project)
 8module = %(project).wsgi:application
 9
10master = true
11processes = 5
12
13uid = %(username)
14socket = /run/uwsgi/%(project).sock
15chown-socket = %(username):nginx
16chmod-socket = 660
17vacuum = true

保存并关闭文件完成后. 您的第二个项目应该准备好现在。

创建 uWSGI 的 Systemd 单元文件

我们现在有配置文件,我们需要为我们的Django项目服务,但我们还没有自动化这个过程。

我们将创建单元文件在 /etc/systemd/system 目录中,在那里存储用户创建的单元文件. 我们将我们的文件称为 uwsgi.service:

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

從「[單元]」部分開始,用於指定元數據,我們只會在這裡列出我們的服務的描述:

1[Unit]
2Description=uWSGI Emperor service

接下来,我们将打开[服务]部分。我们将使用ExecStartPre指令来设置我们需要运行我们的服务器的零件。这将确保创建了/run/uwsgi目录,我们的正常用户将其与 Nginx 群组作为组所有者拥有。有p旗和chown命令的mkdir都成功返回,即使它们已经存在。

对于ExecStart指令规定的实际启动命令,我们会指向uwsgi可执行的命令,我们会告诉它在Emperor模式下运行,允许它使用它在/etc/uwsgi/sites中找到的文件来管理多个应用程序。

 1[Unit]
 2Description=uWSGI Emperor service
 3
 4[Service]
 5ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown user:nginx /run/uwsgi'
 6ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites
 7Restart=always
 8KillSignal=SIGQUIT
 9Type=notify
10NotifyAccess=all

现在,我们所需要做的只是添加[安装]部分,这使我们能够指定服务何时自动启动,我们将我们的服务与多用户系统状态相关联,每次系统设置为多用户(正常操作状态),我们的服务将被激活:

 1[Unit]
 2Description=uWSGI Emperor service
 3
 4[Service]
 5ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown user:nginx /run/uwsgi'
 6ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites
 7Restart=always
 8KillSignal=SIGQUIT
 9Type=notify
10NotifyAccess=all
11
12[Install]
13WantedBy=multi-user.target

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

我们将无法在此时成功启动服务,因为它依赖于nginx用户的可用性,我们将不得不等待在安装 Nginx 后启动 uWSGI 服务。

安装和配置 Nginx 作为反向代理

有了 uWSGI 配置并做好准备,我们现在可以安装和配置 Nginx 作为我们的反向代理程序。

1sudo yum install nginx

一旦安装了 Nginx,我们可以继续编辑主要配置文件:

1sudo nano /etc/nginx/nginx.conf

在此文件中,在现有的服务器块旁边,我们将为每个网站创建一个额外的服务器块:

 1http {
 2
 3    . . .
 4
 5    include /etc/nginx/conf.d/*.conf;
 6
 7    server {
 8    }
 9
10    server {
11    }
12
13    server {
14        listen 80 default_server;
15        server_name localhost;
16
17        . . .

我们创建的块将保留我们的uWSGI站点的配置,我们现在将涵盖我们需要的第一个服务器块的指令。

首先,我们需要告诉服务器块哪个端口号和域名应响应,我们将假设您对每个网站都有一个域名:

1server {
2    listen 80;
3    server_name firstsite.com www.firstsite.com;
4}

接下來,我們會告訴 Nginx 我們不必擔心缺失的 favicon. 然後我們會指定我們第一個網站的靜態資產在這些檔案被要求時所收集的目錄。

1server {
2    listen 80;
3    server_name firstsite.com www.firstsite.com;
4
5    location = favicon.ico { access_log off; log_not_found off; }
6    location /static/ {
7        root /home/user/firstsite;
8    }
9}

接下来,我们将创建一个 catch-all 位置块,将所有额外的查询直接传送到 uWSGI. 我们将包括在 /etc/nginx/uwsgi_params 文件中发现的 uwsgi` 参数,并将流量传送到 uWSGI 服务器设置的接口:

 1server {
 2    listen 80;
 3    server_name firstsite.com www.firstsite.com;
 4
 5    location = favicon.ico { access_log off; log_not_found off; }
 6    location /static/ {
 7        root /home/user/firstsite;
 8    }
 9
10    location / {
11        include uwsgi_params;
12        uwsgi_pass unix:/run/uwsgi/firstsite.sock;
13    }
14}

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

我们的其他网站的第二个服务器块将几乎相同。您可以复制和粘贴我们刚刚创建的服务器块,以便开始。您需要修改网站应响应的域名、网站静态文件的位置和网站的插槽文件:

 1server {
 2    listen 80;
 3    server_name secondsite.com www.secondsite.com;
 4
 5    location = favicon.ico { access_log off; log_not_found off; }
 6    location /static/ {
 7        root /home/user/secondsite;
 8    }
 9
10    location / {
11        include uwsgi_params;
12        uwsgi_pass unix:/run/uwsgi/secondsite.sock;
13    }
14}

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

检查 Nginx 文件的语法,以确保您没有任何错误:

1sudo nginx -t

如果没有报告错误,我们的文件处于良好状态。

我们有一个额外的任务,我们必须完成,使我们的网站正常工作. 由于 Nginx 直接处理静态文件,它需要访问适当的目录. 我们需要为我们的主目录提供可执行的权限,这是唯一缺乏的权限。

最安全的方法是将 Nginx 用户添加到我们自己的用户组中,然后我们可以将可执行的权限添加到我们主目录的组所有者中,为 Nginx 提供足够的访问权限来服务这些文件:

1sudo usermod -a -G user nginx
2chmod 710 /home/user

现在,我们可以启动 Nginx 服务器和 uWSGI 流程:

1sudo systemctl start nginx
2sudo systemctl start uwsgi

您现在应该能够通过前往各自的域名来接触您的两个项目,公共和行政界面都应该按照预期工作。

如果情况顺利,您可以通过键入两个服务在启动时自动启动:

1sudo systemctl enable nginx
2sudo systemctl enable uwsgi

结论

在本指南中,我们已经设置了两个Django项目,每个在自己的虚拟环境中。我们已经配置了uWSGI来独立使用每个项目配置的虚拟环境来服务每个项目。

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

Published At
Categories with 技术
comments powered by Disqus