如何在 Ubuntu 16.04 上使用 Apache 和 mod_wsgi 服务 Django 应用程序
介绍
Django 是一个强大的 Web 框架,可以帮助您快速启动 Python 应用程序或网站。 Django 包括一个简化的开发服务器,用于在本地测试您的代码,但对于任何与生产相关的东西,即使是轻微的生产相关的东西,都需要一个更安全和更强大的 Web 服务器。
在本指南中,我们将演示如何在 Python 虚拟环境中安装和配置 Django。然后,我们将在我们的应用程序前面设置 Apache,以便它可以在将需要应用程序逻辑的请求传递给 Django 应用程序之前直接处理客户端请求。我们将使用 mod_wsgi
Apache 模块来执行此操作,该模块可以通过 WSGI 接口规范与 Django 进行通信。
先决条件和目标
为了完成本指南,您应该有一个新的 Ubuntu 16.04 服务器实例,其中非根用户配置了 sudo
权限。您可以通过我们的初始服务器设置指南了解如何设置它。
我们将在 Python 虚拟环境中安装 Django。将 Django 安装到特定于项目的环境中将允许单独处理项目及其需求。
一旦我们的应用程序启动并运行,我们将配置 Apache 以与 Django 应用程序交互。它将使用 mod_wsgi
Apache 模块执行此操作,该模块可以将 HTTP 请求转换为由称为 WSGI 的规范定义的可预测应用程序格式。您可以通过阅读本指南的链接部分了解更多关于 WSGI 的信息。
让我们开始吧。
从 Ubuntu 存储库安装软件包
要开始这个过程,我们将从 Ubuntu 存储库下载并安装我们需要的所有项目。这将包括 Apache 网络服务器,用于与我们的 Django 应用程序交互的 mod_wsgi
模块,以及 pip
,可用于下载我们的 Python 相关的 Python 包管理器工具。
要获得我们需要的一切,请更新服务器的本地包索引,然后安装适当的包。
如果您将 Django 与 Python 2 一起使用,则需要的命令是:
- sudo apt-get update
- sudo apt-get install python-pip apache2 libapache2-mod-wsgi
相反,如果您将 Django 与 Python 3 一起使用,则您将需要一个替代的 Apache 模块和 pip
包。在这种情况下适当的命令是:
- sudo apt-get update
- sudo apt-get install python3-pip apache2 libapache2-mod-wsgi-py3
配置 Python 虚拟环境
现在我们有了 Ubuntu 存储库中的组件,我们可以开始处理我们的 Django 项目了。第一步是创建一个 Python 虚拟环境,这样我们的 Django 项目将与系统工具和我们可能正在处理的任何其他 Python 项目分开。
我们需要安装 virtualenv
命令来创建这些环境。我们可以使用 pip
获取它。
如果您使用的是 Python 2,请键入:
- sudo pip install virtualenv
如果您使用的是 Python 3,请键入:
- sudo pip3 install virtualenv
安装了 virtualenv
后,我们就可以开始构建我们的项目了。创建一个您希望保留项目的目录并移至该目录:
- mkdir ~/myproject
- cd ~/myproject
在项目目录中,通过键入以下命令创建 Python 虚拟环境:
- virtualenv myprojectenv
这将在您的 myproject
目录中创建一个名为 myprojectenv
的目录。在内部,它将安装一个本地版本的 Python 和一个本地版本的 pip
。我们可以使用它为我们的项目安装和配置一个独立的 Python 环境。
在我们安装项目的 Python 要求之前,我们需要激活虚拟环境。您可以通过键入以下内容来做到这一点:
- source myprojectenv/bin/activate
您的提示应更改为表明您现在正在 Python 虚拟环境中操作。它看起来像这样:(myprojectenv)user@host:~/myproject$
。
在您的虚拟环境处于活动状态的情况下,使用 pip
的本地实例安装 Django:
不管你使用的是Python 2还是Python 3,当虚拟环境被激活时,我们应该使用pip
命令(不是pip3
)。
- pip install django
创建和配置一个新的 Django 项目
现在 Django 已安装在我们的虚拟环境中,我们可以创建实际的 Django 项目文件。
创建 Django 项目
由于我们已经有了一个项目目录,我们将告诉 Django 在这里安装文件。它会创建一个带有实际代码的二级目录,这很正常,并在该目录下放置一个管理脚本。关键是末尾的点告诉 Django 在当前目录中创建文件:
- django-admin.py startproject myproject .
调整项目设置
我们应该对我们新创建的项目文件做的第一件事是调整设置。使用文本编辑器打开设置文件:
- nano myproject/settings.py
为简单起见,我们将在本指南中使用默认的 SQLite 数据库,因此我们实际上不需要进行太多更改。我们将专注于配置允许的主机以限制我们响应的域和配置静态文件目录,Django 将在其中放置静态文件,以便 Web 服务器可以轻松地提供这些文件。
首先找到 ALLOWED_HOSTS
行。在方括号内,输入服务器的公共 IP 地址、域名或两者。每个值都应该用引号括起来并用逗号分隔,就像普通的 Python 列表一样:
. . .
ALLOWED_HOSTS = ["server_domain_or_IP"]
. . .
在文件的底部,我们将添加一行来配置这个目录。 Django 使用 STATIC_ROOT
设置来确定这些文件应该放在的目录。我们将使用一些 Python 来告诉它使用项目主目录中名为 \static 的目录:
. . .
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
完成后保存并关闭文件。
完成初始项目设置
现在,我们可以使用管理脚本将初始数据库模式迁移到我们的 SQLite 数据库:
- cd ~/myproject
- ./manage.py makemigrations
- ./manage.py migrate
通过键入以下内容为项目创建管理用户:
- ./manage.py createsuperuser
您必须选择一个用户名,提供一个电子邮件地址,然后选择并确认一个密码。
我们可以通过键入以下内容将所有静态内容收集到我们配置的目录位置:
- ./manage.py collectstatic
您将必须确认该操作。静态文件将放置在项目目录中名为 static
的目录中。
现在,我们可以调整我们的防火墙设置以允许流量到我们将在端口 8000 上运行的 Django 开发服务器。如果您按照先决条件中的初始服务器设置指南进行操作,则当前应该启用了 UFW 防火墙。
通过键入以下内容允许连接到开发服务器:
- sudo ufw allow 8000
最后,您可以使用以下命令启动 Django 开发服务器来测试您的项目:
- ./manage.py runserver 0.0.0.0:8000
在您的网络浏览器中,访问您服务器的域名或 IP 地址,后跟 :8000
:
http://server_domain_or_IP:8000
你应该看到默认的 Django 索引页面:

如果将 /admin
附加到地址栏中的 URL 末尾,系统将提示您输入使用 createsuperuser
命令创建的管理用户名和密码:

通过身份验证后,您可以访问默认的 Django 管理界面:

完成探索后,在终端窗口中按 CTRL-C 关闭开发服务器。
我们现在暂时完成了 Django,因此我们可以通过键入以下命令退出虚拟环境:
- deactivate
配置阿帕奇
现在您的 Django 项目正在运行,我们可以将 Apache 配置为前端。它接收到的客户端连接将被转换为 Django 应用程序期望使用 mod_wsgi
模块的 WSGI 格式。这应该在之前安装时自动启用。
要配置 WSGI pass,我们需要编辑默认的虚拟主机文件:
- sudo nano /etc/apache2/sites-available/000-default.conf
我们可以保留文件中已经存在的指令。我们只需要添加一些额外的项目。
首先,让我们配置静态文件。我们将使用一个别名来告诉 Apache 将任何以 /static
开头的请求映射到我们项目文件夹中的“static”目录。我们之前在那里收集了静态资产。我们将设置别名和然后使用目录块授予对相关目录的访问权限:
<VirtualHost *:80>
. . .
Alias /static /home/sammy/myproject/static
<Directory /home/sammy/myproject/static>
Require all granted
</Directory>
</VirtualHost>
接下来,我们将授予对存储 Django 代码的二级项目目录中的 wsgi.py
文件的访问权限。为此,我们将使用一个目录部分,其中包含一个文件部分。我们将授予对该嵌套结构内部文件的访问权限:
<VirtualHost *:80>
. . .
Alias /static /home/sammy/myproject/static
<Directory /home/sammy/myproject/static>
Require all granted
</Directory>
<Directory /home/sammy/myproject/myproject>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
</VirtualHost>
配置完成后,我们就可以构建文件中实际处理 WSGI 传递的部分。我们将使用守护进程模式来运行 WSGI 进程,这是推荐的配置。我们可以使用 WSGIDaemonProcess
指令来设置它。
该指令为进程取一个任意名称。我们将使用 myproject
来保持一致。之后,我们设置了 Python 主页,Apache 可以在其中找到可能需要的所有组件。由于我们使用了虚拟环境,因此我们可以将其直接指向我们的基本虚拟环境目录。之后,我们将 Python 路径设置为指向我们的 Django 项目的基础。
接下来,我们需要指定进程组。这应该指向我们为 WSGIDaemonProcess
指令选择的相同名称(在我们的例子中是 myproject
)。最后,我们需要设置脚本别名,以便 Apache 将对根域的请求传递给 wsgi.py
文件:
<VirtualHost *:80>
. . .
Alias /static /home/sammy/myproject/static
<Directory /home/sammy/myproject/static>
Require all granted
</Directory>
<Directory /home/sammy/myproject/myproject>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess myproject python-home=/home/sammy/myproject/myprojectenv python-path=/home/sammy/myproject
WSGIProcessGroup myproject
WSGIScriptAlias / /home/sammy/myproject/myproject/wsgi.py
</VirtualHost>
完成这些更改后,保存并关闭文件。
结束一些权限问题
如果您使用的是本文默认使用的 SQLite 数据库,则需要允许 Apache 进程访问该文件。
为此,第一步是更改权限,以便数据库的组所有者可以读写。数据库文件默认名为 db.sqlite3
,它应该位于您的基础项目目录中:
- chmod 664 ~/myproject/db.sqlite3
之后,我们需要给 Apache 运行的组,www-data
组,文件的组所有权:
- sudo chown :www-data ~/myproject/db.sqlite3
为了写入文件,我们还需要授予 Apache 组对数据库父目录的所有权:
- sudo chown :www-data ~/myproject
我们需要再次通过防火墙进行调整。我们不再需要打开端口 8000,因为我们通过 Apache 进行代理,因此我们可以删除该规则。然后我们可以添加一个例外以允许流量到 Apache 进程:
- sudo ufw delete allow 8000
- sudo ufw allow 'Apache Full'
检查您的 Apache 文件以确保您没有犯任何语法错误:
- sudo apache2ctl configtest
只要最后一行输出看起来像这样,您的文件就完好无损:
Output. . .
Syntax OK
完成这些步骤后,您就可以重新启动 Apache 服务以实施您所做的更改。键入以下命令重新启动 Apache:
- sudo systemctl restart apache2
您现在应该能够通过转到服务器的域名或 IP 地址来访问您的 Django 站点,而无需指定端口。常规站点和管理界面应按预期运行。
下一步
在验证您的应用程序可访问后,保护应用程序的流量非常重要。
如果您的应用程序有域名,那么保护您的应用程序的最简单方法是使用 Let's Encrypt 提供的免费 SSL 证书。按照我们的 Let's Encrypt 16.04 Apache 指南学习如何设置它。
如果您的应用程序没有域名并将其用于您自己的目的或测试,您始终可以创建一个自签名证书。您可以通过我们关于在 Ubuntu 16.04 上为 Apache 创建自签名 SSL 证书的指南了解如何进行设置。
结论
在本指南中,我们在自己的虚拟环境中设置了一个 Django 项目。我们已使用 mod_wsgi
配置 Apache 来处理客户端请求并与 Django 应用程序交互。
Django 通过提供许多通用部分使创建项目和应用程序变得简单,让您专注于独特的元素。通过利用本文中描述的通用工具链,您可以轻松地为您从单个服务器创建的应用程序提供服务。