如何在Debian8上使用Apache和mod wsgi服务Django应用程序
介绍
Django 是一个强大的 Web 框架,可以帮助您快速启动 Python 应用程序或网站。 Django 包含一个简化的开发服务器,用于在本地测试您的代码,但对于任何与生产相关的事情,都需要一个更安全、更强大的 Web 服务器。
在本指南中,我们将演示如何在 Python 虚拟环境中安装和配置 Django。 然后,我们将在我们的应用程序前面设置 Apache,以便它可以在将需要应用程序逻辑的请求传递给 Django 应用程序之前直接处理客户端请求。 我们将使用可以通过 WSGI 接口规范与 Django 通信的 mod_wsgi
Apache 模块来执行此操作。
先决条件和目标
为了完成本指南,您应该拥有一个全新的 Debian 8 服务器实例,该实例具有配置了 sudo
权限的非 root 用户。 您可以通过我们的 初始服务器设置指南 来了解如何设置它。
我们将在 Python 虚拟环境中安装 Django。 将 Django 安装到特定于您的项目的环境中将允许单独处理您的项目及其要求。
一旦我们的应用程序启动并运行,我们将配置 Apache 以与 Django 应用程序交互。 它将使用 mod_wsgi
Apache 模块来完成此操作,该模块可以将 HTTP 请求转换为由称为 WSGI 的规范定义的可预测的应用程序格式。 您可以通过阅读 本指南 上的链接部分来了解有关 WSGI 的更多信息。
让我们开始吧。
从 Debian 存储库安装软件包
要开始这个过程,我们将从 Debian 存储库下载并安装我们需要的所有项目。 这将包括 Apache Web 服务器、用于与我们的 Django 应用程序交互的 mod_wsgi
模块,以及可用于下载我们的 Python 相关工具的 Python 包管理器 pip
。
要获得我们需要的一切,请更新服务器的本地包索引,然后安装适当的包。
如果您将 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
现在我们已经拥有了 Debian 存储库中的组件,我们可以开始处理我们的 Django 项目了。
配置 Python 虚拟环境
第一步是创建一个 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 ~/myproject/myprojectenv/bin/activate
您的提示应更改以指示您现在正在 Python 虚拟环境中操作。 它看起来像这样:(myprojectenv)user@host:~/myproject$
。
激活虚拟环境后,使用 pip
的本地实例安装 Django:
注意: 虚拟环境使用自己的Python版本和相关工具。 无论您使用的是 Python 2 还是 Python 3,在激活虚拟环境时,都应该使用 pip
命令(而不是 pip3
)。
pip install django
这将在您的 Python 虚拟环境中安装 Django 包。
创建和配置一个新的 Django 项目
现在 Django 已安装在我们的虚拟环境中,我们可以创建实际的 Django 项目文件。
创建 Django 项目
由于我们已经在 ~/myproject
有一个父项目目录,我们将告诉 Django 将文件安装在此处。 该命令将创建一个包含实际代码的二级目录。 它还将在当前项目目录中放置一个管理脚本。 实现正确目录结构的关键是在项目名称后列出父目录:
django-admin.py startproject myproject ~/myproject
您最终应该得到一个如下所示的目录结构:
. └── ./myproject/ # parent project directory ├── manage.py # Django management script ├── myproject/ # project code directory │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── myprojectenv/ # project virtual environment directory └── . . .
检查您的目录结构是否与此一致有助于以后尽量减少错误。
调整项目设置
我们应该对新创建的项目文件做的第一件事是调整设置。 使用文本编辑器打开设置文件:
nano ~/myproject/myproject/settings.py
为简单起见,我们将在本指南中使用默认的 SQLite 数据库,因此我们实际上不需要进行太多更改。 我们将专注于配置允许的主机以限制我们响应的域并配置静态文件目录,Django 将在其中放置静态文件,以便 Web 服务器可以轻松地提供这些文件。
首先找到 ALLOWED_HOSTS
行。 在方括号内,输入服务器的公共 IP 地址、域名或两者。 每个值都应该用引号括起来并用逗号分隔,就像普通的 Python 列表一样。 最好添加本地地址,例如 127.0.0.1
和 127.0.1.1
:
~/myproject/myproject/settings.py
. . . ALLOWED_HOSTS = ["server_domain_or_IP", "127.0.0.1", "127.0.1.1"] . . .
在文件的底部,我们将设置 Django 的 STATIC_ROOT
。 Django 可以收集所有静态资产并将其输出到一个已知目录中,以便 Web 服务器可以直接为它们提供服务。 我们将使用一点 Python 来告诉它在我们项目的主目录中使用一个名为“static”的目录:
~/myproject/myproject/settings.py
. . . STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
完成后保存并关闭文件。
完成初始项目设置
现在,我们可以使用管理脚本将初始数据库模式迁移到我们的 SQLite 数据库:
cd ~/myproject ./manage.py makemigrations ./manage.py migrate
通过键入以下内容为项目创建管理用户:
./manage.py createsuperuser
您必须选择用户名,提供电子邮件地址,然后选择并确认密码。
我们可以通过键入以下命令将所有静态内容收集到我们使用 STATIC_ROOT
定义的目录位置:
./manage.py collectstatic
您必须确认操作。 正如预期的那样,静态文件将放置在项目目录中名为 static
的目录中。
您可能需要调整防火墙设置以允许流量到我们的 Django 开发服务器,我们将在端口 8000 上运行该服务器。
如果您正在运行 ufw
防火墙,您可以通过键入以下内容来允许到端口 8000 的流量:
sudo ufw allow 8000
如果您正在运行 iptables
,您需要的确切命令取决于您当前的防火墙配置。 对于大多数配置,此命令应该可以工作:
sudo iptables -I INPUT -p tcp --dport 8000 -j ACCEPT
最后,您可以使用以下命令启动 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
shell 提示符的 (myprojectenv)
前缀应该会消失。
配置阿帕奇
现在您的 Django 项目正在运行,我们可以将 Apache 配置为前端。 它接收到的客户端连接将被转换为 Django 应用程序使用 mod_wsgi
模块所期望的 WSGI 格式。 这应该在之前安装时自动启用。
要配置 WSGI pass,我们需要编辑默认的虚拟主机文件:
sudo nano /etc/apache2/sites-available/000-default.conf
我们可以保留文件中已经存在的指令。 我们只需要添加一些额外的项目。
首先,让我们配置静态文件。 我们将使用别名告诉 Apache 将以 /static
开头的任何请求映射到我们项目文件夹中的“静态”目录。 我们之前在那里收集了静态资产。 我们将设置别名,然后使用目录块授予对相关目录的访问权限:
/etc/apache2/sites-available/000-default.conf
<VirtualHost *:80> . . . Alias /static /home/sammy/myproject/static <Directory /home/sammy/myproject/static> Require all granted </Directory> </VirtualHost>
接下来,我们将授予对存储 Django 代码的二级项目目录中的 wsgi.py
文件的访问权限。 为此,我们将使用一个目录部分,其中包含一个文件部分。 我们将授予对该嵌套结构内文件的访问权限:
/etc/apache2/sites-available/000-default.conf
<VirtualHost *:80> . . . Alias /static /home/sammy/myproject/static <Directory /home/sammy/myproject/static> Require all granted </Directory> # Next, add the following directory block <Directory /home/sammy/myproject/myproject> <Files wsgi.py> Require all granted </Files> </Directory> </VirtualHost>
配置完成后,我们就可以构建文件中实际处理 WSGI pass 的部分了。 我们将使用守护模式来运行 WSGI 进程,这是推荐的配置。 我们可以使用 WSGIDaemonProcess
指令来设置它。
该指令采用进程的任意名称。 我们将使用 myproject
来保持一致。 之后,我们设置了 Python 主页,Apache 可以在其中找到所有可能需要的组件。 由于我们使用了虚拟环境,我们可以将其直接指向我们的基本虚拟环境目录。 之后,我们将 Python 路径设置为指向 Django 项目的基础。
接下来,我们需要指定进程组。 这应该指向我们为 WSGIDaemonProcess
指令选择的相同名称(在我们的例子中是 myproject
)。 最后,我们需要设置脚本别名,以便 Apache 将对根域的请求传递给 wsgi.py
文件:
/etc/apache2/sites-available/000-default.conf
<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 chmod 775 ~/myproject
之后,我们需要给 Apache 运行组,www-data
组,文件的组所有权:
sudo chown :www-data ~/myproject/db.sqlite3
为了写入文件,我们还需要授予 Apache 组对数据库父目录的所有权:
sudo chown :www-data ~/myproject
我们需要再次通过防火墙进行调整。 我们不再需要打开 8000 端口,因为我们通过 Apache 进行代理,所以我们可以删除该规则。 然后我们可以添加一个例外以允许流量到 Apache 进程。
如果您使用 ufw
,您可以通过键入:
sudo ufw delete allow 8000 sudo ufw allow 'Apache Full'
如果您使用 iptables
,则相应的命令将如下所示:
sudo iptables -D INPUT -p tcp --dport 8000 -j ACCEPT sudo iptables -I INPUT -p tcp --dport 80 -j ACCEPT
检查您的 Apache 文件以确保您没有犯任何语法错误:
sudo apache2ctl configtest
只要输出的最后一行看起来像这样,您的文件就处于良好状态:
Output. . . Syntax OK
完成这些步骤后,您就可以重新启动 Apache 服务以实施您所做的更改。 通过键入以下命令重新启动 Apache:
sudo systemctl restart apache2
您现在应该能够通过转到服务器的域名或 IP 地址来访问您的 Django 站点,而无需指定端口。 常规站点和管理界面应按预期运行。
下一步
在验证您的应用程序可访问后,保护您的应用程序的流量非常重要。
如果您的应用程序有域名,保护您的应用程序的最简单方法是使用 Let's Encrypt 提供的免费 SSL 证书。 遵循我们的 Let's Encrypt Debian 8 上 Apache 指南,了解如何进行设置。
如果您 没有 应用程序的域名,并且将其用于您自己的目的或测试,您始终可以创建自签名证书。 您可以通过我们的 指南了解如何在 Debian 8 上为 Apache 创建自签名 SSL 证书。
结论
在本指南中,我们在自己的虚拟环境中设置了一个 Django 项目。 我们已经使用 mod_wsgi
配置 Apache 来处理客户端请求并与 Django 应用程序交互。
Django 通过提供许多通用部分使创建项目和应用程序变得简单,让您可以专注于独特的元素。 通过利用本文中描述的通用工具链,您可以轻松地为您从单个服务器创建的应用程序提供服务。