如何为在CentOS 7 Django的应用程序与uWSGI和Nginx的

Django是一个功能强大的Web框架,可以帮助您得到您的Python应用程序或网站离地面。 Django包含局部测试代码的简化开发服务器,但对于任何稍微的生产有关,更安全,更强大的Web服务器...

介绍

Django是一个强大的网络框架,可以帮助你让你的Python应用程序或网站离地面。 Django包括一个用于在本地测试代码的简化开发服务器,但是对于与生产有关的任何事情,需要一个更安全和更强大的Web服务器。

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

先决条件和目标

为了完成这个指南,你应该有一个非root用户新鲜的CentOS 7服务器实例sudo配置权限。 你可以学习如何通过我们的运行设置此服务器初始设置指南

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

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

让我们开始吧。

安装和配置VirtualEnv和VirtualEnvWrapper

我们将在自己的虚拟环境中安装我们的Django项目,以隔离每个项目的需求。 要做到这一点,我们就可以安装virtualenv ,它可以创造Python的虚拟环境,并virtualenvwrapper ,它增加了一些实用性改进了virtualenv工作流程。

我们将同时安装使用这些组件的pip ,Python的包管理器。 为了得到pip ,我们首先需要启用EPEL软件库。 我们可以轻松地通过键入:

sudo yum install epel-release

一旦EPEL被启用,我们可以安装pip通过键入:

sudo yum install python-pip

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

sudo pip install virtualenv virtualenvwrapper

安装这些组件,现在我们可以用它需要与合作的信息来配置我们的外壳virtualenvwrapper脚本。 我们的虚拟环境都将在我们称为home文件夹放在一个目录内的Env以方便访问。 这是通过一个叫做环境变量配置WORKON_HOME 我们可以将其添加到我们的shell初始化脚本中,并且可以获取虚拟环境包装器脚本。

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

echo "export WORKON_HOME=~/Env" >> ~/.bashrc
echo "source /usr/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你的home目录中。 这是一个用于处理项目各个方面的管理脚本和用于容纳实际项目代码的同名的另一个目录。

移动到第一级目录,以便我们可以开始设置我们的示例项目的最低要求。

cd ~/firstsite

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

./manage.py migrate

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

./manage.py createsuperuser

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

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

nano firstsite/settings.py

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

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

保存并在完成后关闭文件。 现在,收集我们网站的静态元素,并通过键入以下内容将其放在该目录中:

./manage.py collectstatic

您可以键入“是”以确认操作并收集静态内容。 将有一个名为新目录static在您的项目目录。

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

./manage.py runserver 0.0.0.0:8080

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

http://server_domain_or_IP:8080

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

Django示例网站

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

Django管理员登录

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

Django管理界面

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

创建第二个项目

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

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

cd ~
mkvirtualenv secondsite
pip install django

新的环境将被创建改变,让你以前的虚拟环境。 这个Django实例完全独立于您配置的另一个实例。 这允许您独立管理它们并根据需要进行自定义。

创建第二个项目并移动到项目目录:

django-admin.py startproject secondsite
cd ~/secondsite

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

./manage.py migrate
./manage.py createsuperuser

打开设置文件:

nano secondsite/settings.py

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

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

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

./manage.py collectstatic

最后,启动开发服务器测试网站:

./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的标准接口与应用程序通信。 要了解更多关于这一点,阅读这部分我们的指南有关建立uWSGI和Nginx的在Ubuntu 14.04。

安装uWSGI

与上面链接的指南不同,在本教程中,我们将在全球安装uWSGI。 这将在处理多个Django项目时创建较少的摩擦。 在我们可以安装uWSGI之前,我们需要软件依赖的Python开发文件。 我们也需要一个编译器。 我们可以用得到这两种yum

sudo yum install python-devel gcc

现在,发展的文件都可以,我们可以通过全球范围内安装uWSGI pip键入以下命令:

sudo pip install uwsgi

我们可以通过传递其中一个站点的信息来快速测试此应用程序服务器。 例如,我们可以通过键入以下内容来告诉它服务我们的第一个项目:

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

在这里,我们已经告诉uWSGI使用我们位于我们的虚拟环境的~/Env目录,改变我们项目的目录,并使用wsgi.py存储在我们内心中的文件firstsite目录服务文件。 对于我们的演示,我们告诉它要服务于HTTP端口8080 如果你到服务器的域名,或在浏览器中,然后通过IP地址:8080 ,你将再次看到你的网站(在静态元素/admin界面将无法工作)。 当您完成测试此功能时,在终端中键入CTRL-C。

创建配置文件

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

创建一个将保存您的配置文件的目录。 由于这是一个全球性的过程中,我们将创建一个名为目录/etc/uwsgi/sites来存储配置文件。 在创建目录后移动到目录:

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

在这个目录中,我们将放置我们的配置文件。 我们需要一个配置文件为我们正在服务的每个项目。 该uWSGI过程可能需要配置文件在各种格式,但是我们会用.ini文件,由于其简单。

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

sudo nano firstsite.ini

在内部,我们必须从开始[uwsgi]节标题。 我们所有的信息将在这个标题下面。 我们还将使用变量来使我们的配置文件更可重用。 头后,设置了一个名为变量project与第一个项目的名称。 使用您拥有项目文件的普通用户名设置另一个变量。 添加一个变量,名为base ,使用您的用户名来建立你的用户的主目录的路径:

[uwsgi]
project = firstsite
username = user
base = /home/%(username)

接下来,我们需要配置uWSGI,以便它能正确处理我们的项目。 我们需要通过设置改变到根项目目录chdir选项。 我们可以结合家里目录和项目名称设置,我们使用先前设置%( variable_name )语法。 这将被读取配置时的变量的值替换。

以类似的方式,我们将指出我们项目的虚拟环境。 通过设置模块,我们可以准确地指示如何与我们的项目(通过导入“应用程序”,从可调用接口wsgi.py项目目录中的文件)。 这些项目的配置将如下所示:

[uwsgi]
project = firstsite
username = user
base = /home/%(username)

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

我们要创建一个有5个工人的主进程。 我们可以这样做:

[uwsgi]
project = firstsite
username = user
base = /home/%(username)

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服务器写访问权限。 本身将被置于内的插座/run/uwsgi目录(我们将创建一个有点这个目录),其中既uWSGI和Nginx的可以达到它。 我们将设置vacuum ,以便插槽文件将在该服务停止时自动清理选项:

[uwsgi]
project = firstsite
username = user
base = /home/%(username)

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

master = true
processes = 5

uid = %(username)
socket = /run/uwsgi/%(project).sock
chown-socket = %(username):nginx
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 = firstsite
username = user
base = /home/%(username)

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

master = true
processes = 5

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

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

为uWSGI创建Systemd单元文件

我们现在有了我们需要的配置文件来为我们的Django项目服务,但是我们还没有自动化进程。 接下来,我们将创建一个Systemd单元文件,以便在引导时自动启动uWSGI。

我们将在创建单元文件/etc/systemd/system ,其中用户创建单元文件保存的目录。 我们将调用我们的文件uwsgi.service

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

先从[Unit]部分,它是用来指定的元数据。 我们将在这里简单地描述我们的服务:

[Unit]
Description=uWSGI Emperor service

接下来,我们将打开[Service]部分。 我们将使用ExecStartPre指令设置我们需要运行我们的服务器的作品。 这将确保该/run/uwsgi目录中创建,我们的普通用户使用Nginx的组作为该组的所有者拥有它。 两者mkdir-p标志和chown命令返回成功,即使它们已经存在。 这是我们想要的。

对于实际的启动命令,由指定的ExecStart指令,我们将指向uwsgi可执行文件。 我们会告诉它以“皇帝模式”下运行,使其能够管理多个应用程序中使用它找到的文件/etc/uwsgi/sites 我们还将添加Systemd所需的部分以正确管理进程。 这些是从uWSGI文档采取在这里

[Unit]
Description=uWSGI Emperor service

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

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

[Unit]
Description=uWSGI Emperor service

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

[Install]
WantedBy=multi-user.target

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

我们将无法在这一点上成功启动该服务,因为它依赖于nginx用户是可用的。 我们将不得不等待启动uWSGI服务,直到Nginx安装后。

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

通过配置uWSGI并准备好,我们现在可以安装和配置Nginx作为我们的反向代理。 这可以下载和安装使用yum

sudo yum install nginx

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

sudo nano /etc/nginx/nginx.conf

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

http {

    . . .

    include /etc/nginx/conf.d/*.conf;

    server {
    }

    server {
    }

    server {
        listen 80 default_server;
        server_name localhost;

        . . .

我们创建的块将保存我们的uWSGI站点的配置。 我们将覆盖我们在第一个服务器块中需要的指令。

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

server {
    listen 80;
    server_name firstsite.com www.firstsite.com;
}

接下来,我们将告诉Nginx我们不需要担心丢失的图标。 然后,当请求这些文件时,我们将指定收集第一个网站的静态资产的目录。 Nginx可以把它们直接从该目录的客户端:

server {
    listen 80;
    server_name firstsite.com www.firstsite.com;

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

接下来,我们创建一个catch-all位置块,将所有其他查询直接传递到uWSGI。 我们将包括uwsgi信中参数/etc/nginx/uwsgi_params文件,并通过流量的uWSGI服务器设置了插座:

server {
    listen 80;
    server_name firstsite.com www.firstsite.com;

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

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

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

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

server {
    listen 80;
    server_name secondsite.com www.secondsite.com;

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

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

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

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

sudo nginx -t

如果没有报告错误,我们的文件是在良好的条件。

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

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

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

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

sudo systemctl start nginx
sudo systemctl start uwsgi

现在您应该可以访问他们各自的域名访问您的两个项目。 公共和管理接口都应按预期工作。

如果这样做顺利,您可以通过键入以下命令,使这两个服务在启动时自动启动:

sudo systemctl enable nginx
sudo systemctl enable uwsgi

结论

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

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