如何在 Ubuntu 14.04 上使用 uWSGI 和 Nginx 服务 Django 应用程序

介绍

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

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

前提和目标

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

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

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

让我们开始吧。

安装和配置 VirtualEnv 和 VirtualEnvWrapper

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

我们将使用Python包管理器的pip来安装这两个组件,可以从Ubuntu存储库中获取:

1sudo apt-get update
2sudo apt-get install python-pip

如果你的代码使用Python 3,你可以安装python3-pip包,然后在虚拟环境之外运行时,你必须用pip3命令代替本指南中的pip命令。

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

1sudo pip 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./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 apt-get install python-dev

现在开发文件已经可用,我们可以通过键入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
3base = /home/user

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

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

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

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

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

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

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

我们还会修改插件的权限,因为我们会给网页服务器写入访问权限,我们会设置真空选项,以便在停止服务时自动清除插件文件:

 1[uwsgi]
 2project = firstsite
 3base = /home/user
 4
 5chdir = %(base)/%(project)
 6home = %(base)/Env/%(project)
 7module = %(project).wsgi:application
 8
 9master = true
10processes = 5
11
12socket = %(base)/%(project)/%(project).sock
13chmod-socket = 664
14vacuum = true

这样,我们的第一个项目的 uWSGI 配置就完成了. 保存并关闭文件。

使用变量设置文件的优点是,它使其非常容易重复使用. 复制您的第一个项目的配置文件以作为您的第二个配置文件的基础:

1sudo cp /etc/uwsgi/sites/firstsite.ini /etc/uwsgi/sites/secondsite.ini

使用您的文本编辑器打开第二个配置文件:

1sudo nano /etc/uwsgi/sites/secondsite.ini

我们只需要在该文件中更改一个值,以便为我们的第二个项目工作。

 1[uwsgi]
 2project = secondsite
 3base = /home/user
 4
 5chdir = %(base)/%(project)
 6home = %(base)/Env/%(project)
 7module = %(project).wsgi:application
 8
 9master = true
10processes = 5
11
12socket = %(base)/%(project)/%(project).sock
13chmod-socket = 664
14vacuum = true

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

创建 uWSGI 的 Upstart 脚本

我们现在有我们需要服务我们的Django项目的配置文件,但我们还没有自动化这个过程,接下来,我们将创建一个Upstart脚本,在启动时自动启动uWSGI。

我们将在/etc/init目录中创建一个Upstart脚本,在那里检查这些文件:

1sudo nano /etc/init/uwsgi.conf

首先,为您的 uWSGI 服务设置一个描述,并指示它应该自动运行的运行级别,我们将设置我们的运行级别为 2, 3, 4 和 5,这是传统的多用户运行级别:

1description "uWSGI application server in Emperor mode"
2
3start on runlevel [2345]
4stop on runlevel [!2345]

接下来,我们需要设置用户名和组,该过程将被运行为. 我们将在我们自己的用户名下运行该过程,因为我们拥有所有文件. 对于该组,我们需要将其设置为www-data组, Nginx 将运行在其下方。

1description "uWSGI application server in Emperor mode"
2
3start on runlevel [2345]
4stop on runlevel [!2345]
5
6setuid user
7setgid www-data

最后,我们需要指定要执行的实际命令. 我们需要在皇帝模式下启动uWSGI,并通过我们存储了配置文件的目录。

1description "uWSGI application server in Emperor mode"
2
3start on runlevel [2345]
4stop on runlevel [!2345]
5
6setuid user
7setgid www-data
8
9exec /usr/local/bin/uwsgi --emperor /etc/uwsgi/sites

当你完成时,保存并关闭文件. 我们还不会启动 uWSGI,因为在我们安装 Nginx 之后,我们将不会有 www-data 组。

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

有了 uWSGI 配置并做好准备,我们现在可以安装和配置 Nginx 作为我们的反向代理程序,可以从 Ubuntu 的默认存储库下载:

1sudo apt-get install nginx

一旦安装了 Nginx,我们就可以继续为每个项目创建一个服务器块配置文件,从创建一个服务器块配置文件开始:

1sudo nano /etc/nginx/sites-available/firstsite

内部,我们可以通过指明我们的第一个项目应该可访问的端口号和域名来启动我们的服务器块。

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}

之后,我们可以使用uwsgi_pass指令将流量传送到我们的插槽文件中。我们配置的插槽文件被称为firstproject.sock,并位于我们的项目目录中。

 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:/home/user/firstsite/firstsite.sock;
13    }
14}

这实际上是我们需要的所有配置. 保存并关闭文件,当你完成。

我们将用此作为我们第二个项目的 Nginx 配置文件的基础。

1sudo cp /etc/nginx/sites-available/firstsite /etc/nginx/sites-available/secondsite

在文本编辑器中打开新文件:

1sudo nano /etc/nginx/sites-available/secondsite

在这里,您将不得不将任何firstsite的引用更改为secondsite。您还需要更改server_name,以便您的第二个项目响应不同的域名。

 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:/home/user/secondsite/secondsite.sock;
13    }
14}

保存并关闭文件,当你完成。

接下来,将您的两个新配置文件链接到 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 service nginx configtest

如果没有发现语法错误,您可以重新启动您的 Nginx 服务来加载新的配置:

1sudo service nginx restart

如果你记得从以前,我们从来没有真正启动uWSGI服务器。

1sudo service uwsgi start

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

结论

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

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

Published At
Categories with 技术
comments powered by Disqus