如何在CentOS7上使用Postgres、Nginx和Gunicorn设置Django
介绍
Django 是一个强大的 Web 框架,可以帮助您启动 Python 应用程序或网站。 Django 包含一个简化的开发服务器,用于在本地测试您的代码,但对于任何与生产相关的事情,都需要一个更安全、更强大的 Web 服务器。
在本指南中,我们将演示如何在 CentOS 7 上安装和配置一些组件以支持和服务 Django 应用程序。 我们将设置一个 PostgreSQL 数据库,而不是使用默认的 SQLite 数据库。 我们将配置 Gunicorn 应用程序服务器以与我们的应用程序交互。 然后,我们将设置 Nginx 以反向代理 Gunicorn,使我们能够访问其安全性和性能特性来为我们的应用程序提供服务。
先决条件和目标
为了完成本指南,您应该拥有一个全新的 CentOS 7 服务器实例,该实例具有配置了 sudo
权限的非 root 用户。 您可以通过我们的 初始服务器设置指南 来了解如何设置它。
我们将在虚拟环境中安装 Django。 将 Django 安装到特定于您的项目的环境中将允许单独处理您的项目及其要求。
一旦我们的数据库和应用程序启动并运行,我们将安装和配置 Gunicorn 应用程序服务器。 这将作为我们应用程序的接口,将 HTTP 中的客户端请求转换为我们的应用程序可以处理的 Python 调用。 然后我们将在 Gunicorn 前面设置 Nginx,以利用其高性能的连接处理机制和易于实现的安全特性。
让我们开始吧。
从 EPEL 和 CentOS 存储库安装软件包
要开始这个过程,我们将从 CentOS 存储库下载并安装我们需要的所有项目。 我们还需要使用 EPEL 存储库,其中包含未包含在主要 CentOS 存储库中的额外软件包。 稍后我们将使用 Python 包管理器 pip
来安装一些附加组件。
首先,启用 EPEL 存储库,以便我们可以获取我们需要的组件:
sudo yum install epel-release
有了新的存储库,我们可以在一个命令中安装我们需要的所有部分:
sudo yum install python-pip python-devel postgresql-server postgresql-devel postgresql-contrib gcc nginx
这将安装 Python 包管理器 pip
。 它还将安装 PostgreSQL 数据库系统以及一些库和其他文件,我们将需要与它进行交互并以此为基础进行构建。 我们包含了 GCC 编译器,以便 pip
可以构建软件,并且我们安装了 Nginx 以用作我们安装的反向代理。
为 Django 设置 PostgreSQL
我们将直接进入并为我们的安装设置 PostgreSQL。
配置和启动 PostgreSQL
首先,我们需要初始化 PostgreSQL 数据库。 我们可以通过键入:
sudo postgresql-setup initdb
数据库初始化后,我们可以通过键入以下命令启动 PostgreSQL 服务:
sudo systemctl start postgresql
随着数据库的启动,我们实际上需要调整已填充的配置文件之一中的值。 现在使用编辑器和 sudo
命令打开文件:
sudo nano /var/lib/pgsql/data/pg_hba.conf
该文件负责为数据库系统配置身份验证方法。 目前,它被配置为仅当系统用户与数据库用户匹配时才允许连接。 这对于本地维护任务来说是可以的,但是我们的 Django 实例将为另一个用户配置密码。
我们可以通过修改文件底部的两个 host
行来配置它。 将最后一列(身份验证方法)更改为 md5
。 这将允许密码验证:
. . . # TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all all peer # IPv4 local connections: #host all all 127.0.0.1/32 ident host all all 127.0.0.1/32 md5 # IPv6 local connections: #host all all ::1/128 ident host all all ::1/128 md5
完成后,保存并关闭文件。
随着我们新的配置更改,我们需要重新启动服务。 我们还将启用 PostgreSQL,以便它在引导时自动启动:
sudo systemctl restart postgresql sudo systemctl enable postgresql
创建 PostgreSQL 数据库和用户
现在我们已经按照我们想要的方式启动并运行了 PostgreSQL,我们可以为我们的 Django 应用程序创建一个数据库和数据库用户。
要在本地使用 Postgres,最好临时更改为 postgres
系统用户。 现在通过键入:
sudo su - postgres
当以 postgres
用户身份操作时,您可以直接登录 PostgreSQL 交互式会话而无需进一步验证。 这是由于我们在 pg_hba.conf
文件中的 没有 更改的行:
psql
您将收到一个 PostgreSQL 提示,我们可以在其中设置我们的要求。
首先,为您的项目创建一个数据库:
CREATE DATABASE myproject;
每个命令都必须以分号结尾,因此如果遇到问题,请检查您的命令是否以分号结尾。
接下来,为我们的项目创建一个数据库用户。 确保选择安全密码:
CREATE USER myprojectuser WITH PASSWORD 'password';
现在,我们可以让我们的新用户访问管理我们的新数据库:
GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;
完成后,键入以下命令退出 PostgreSQL 提示:
\q
现在,退出 postgres
用户的 shell 会话,通过键入以下内容返回到普通用户的 shell 会话:
exit
为您的项目创建 Python 虚拟环境
现在我们已经准备好数据库,我们可以开始准备其余的项目需求。 我们将在虚拟环境中安装我们的 Python 需求,以便于管理。
为此,我们首先需要访问 virtualenv
命令。 我们可以用 pip
安装它:
sudo pip 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$
。
在您的虚拟环境处于活动状态时,安装 Django、Gunicorn 和带有 pip
本地实例的 psycopg2
PostgreSQL 适配器:
pip install django gunicorn psycopg2
创建和配置一个新的 Django 项目
安装 Python 组件后,我们可以创建实际的 Django 项目文件。
创建 Django 项目
由于我们已经有一个项目目录,我们将告诉 Django 在此处安装文件。 它将使用实际代码创建一个二级目录,这是正常的,并在此目录中放置一个管理脚本。 关键是末尾的点,它告诉 Django 在当前目录中创建文件:
django-admin.py startproject myproject .
调整项目设置
我们应该对新创建的项目文件做的第一件事是调整设置。 在文本编辑器中打开设置文件:
nano myproject/settings.py
首先找到配置数据库访问的部分。 它将以 DATABASES
开头。 文件中的配置用于 SQLite 数据库。 我们已经为我们的项目创建了一个 PostgreSQL 数据库,所以我们需要调整设置。
使用您的 PostgreSQL 数据库信息更改设置。 我们告诉 Django 使用与 pip
一起安装的 psycopg2
适配器。 我们需要给出数据库名称、数据库用户名、数据库用户名的密码,然后指定数据库位于本地计算机上。 您可以将 PORT
设置保留为空字符串:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'myproject', 'USER': 'myprojectuser', 'PASSWORD': 'password', 'HOST': 'localhost', 'PORT': '', } }
接下来,向下移动到文件的底部并添加一个设置,指示静态文件的放置位置。 这是必要的,以便 Nginx 可以处理对这些项目的请求。 以下行告诉 Django 将它们放在基础项目目录中名为 static
的目录中:
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
完成后保存并关闭文件。
完成初始项目设置
现在,我们可以使用管理脚本将初始数据库模式迁移到我们的 PostgreSQL 数据库:
cd ~/myproject ./manage.py makemigrations ./manage.py migrate
通过键入以下内容为项目创建管理用户:
./manage.py createsuperuser
您必须选择用户名,提供电子邮件地址,然后选择并确认密码。
我们可以通过键入以下命令将所有静态内容收集到我们配置的目录位置:
./manage.py collectstatic
您必须确认操作。 然后,静态文件将放置在项目目录中名为 static
的目录中。
最后,您可以使用以下命令启动 Django 开发服务器来测试您的项目:
./manage.py runserver 0.0.0.0:8000
在您的网络浏览器中,访问您的服务器的域名或 IP 地址,后跟 :8000
:
http://server_domain_or_IP:8000
您应该会看到默认的 Django 索引页面:
如果将 /admin
附加到地址栏中 URL 的末尾,系统将提示您输入使用 createsuperuser
命令创建的管理用户名和密码:
通过身份验证后,您可以访问默认的 Django 管理界面:
完成探索后,在终端窗口中按 CTRL-C 以关闭开发服务器。
测试 Gunicorn 为项目服务的能力
在离开我们的虚拟环境之前,我们要做的最后一件事是测试 Gunicorn 以确保它可以为应用程序服务。 我们可以通过键入以下内容轻松完成此操作:
cd ~/myproject gunicorn --bind 0.0.0.0:8000 myproject.wsgi:application
这将在运行 Django 开发服务器的同一界面上启动 Gunicorn。 您可以返回并再次测试该应用程序。 请注意,管理界面不会应用任何样式,因为 Gunicorn 不知道对此负责的静态内容。
我们通过指定 Django 的 wsgi.py
文件的相对目录路径向 Gunicorn 传递了一个模块,该文件是我们应用程序的入口点,使用 Python 的模块语法。 在该文件中,定义了一个名为 application
的函数,用于与应用程序通信。 要了解有关 WSGI 规范的更多信息,请单击 这里 。
完成测试后,在终端窗口中按 CTRL-C 以停止 Gunicorn。
我们现在已经完成了 Django 应用程序的配置。 我们可以通过键入以下内容退出我们的虚拟环境:
deactivate
创建 Gunicorn Systemd 服务文件
我们已经测试过 Gunicorn 可以与我们的 Django 应用程序交互,但是我们应该实现一种更健壮的方式来启动和停止应用程序服务器。 为此,我们将创建一个 Systemd 服务文件。
在文本编辑器中使用 sudo
权限为 Gunicorn 创建并打开 Systemd 服务文件:
sudo nano /etc/systemd/system/gunicorn.service
从 [Unit]
部分开始,用于指定元数据和依赖项。 我们将在此处描述我们的服务,并告诉 init 系统仅在达到网络目标后才启动它:
[Unit] Description=gunicorn daemon After=network.target
接下来,我们将打开 [Service]
部分。 我们将指定要在其下运行的用户和组。 由于它拥有所有相关文件,因此我们将授予我们常规用户帐户对该过程的所有权。 我们将授予 Nginx 用户组所有权,以便它可以轻松地与 Gunicorn 通信。
然后,我们将绘制工作目录并指定用于启动服务的命令。 在这种情况下,我们必须指定 Gunicorn 可执行文件的完整路径,该可执行文件安装在我们的虚拟环境中。 由于 Nginx 安装在同一台计算机上,因此我们将其绑定到项目目录中的 Unix 套接字。 这比使用网络端口更安全、更快捷。 我们还可以在此处指定任何可选的 Gunicorn 调整。 例如,我们在这种情况下指定了 3 个工作进程:
[Unit] Description=gunicorn daemon After=network.target [Service] User=user Group=nginx WorkingDirectory=/home/user/myproject ExecStart=/home/user/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:/home/user/myproject/myproject.sock myproject.wsgi:application
最后,我们将添加一个 [Install]
部分。 如果我们允许它在启动时启动,这将告诉 Systemd 将该服务链接到什么。 我们希望在常规多用户系统启动并运行时启动此服务:
[Unit] Description=gunicorn daemon After=network.target [Service] User=user Group=nginx WorkingDirectory=/home/user/myproject ExecStart=/home/user/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:/home/user/myproject/myproject.sock myproject.wsgi:application [Install] WantedBy=multi-user.target
这样,我们的 Systemd 服务文件就完成了。 现在保存并关闭它。
我们现在可以启动我们创建的 Gunicorn 服务并启用它,以便它在启动时启动:
sudo systemctl start gunicorn sudo systemctl enable gunicorn
将 Nginx 配置为代理传递到 Gunicorn
现在 Gunicorn 已经设置好了,我们需要配置 Nginx 以将流量传递给进程。
修改 Nginx 配置文件
我们可以继续通过编辑 Nginx 主配置文件来修改服务器块配置:
sudo nano /etc/nginx/nginx.conf
在里面,在已经存在的服务器块上方打开一个新的服务器块:
http { . . . include /etc/nginx/conf.d/*.conf; server { } server { listen 80 default_server; . . .
我们将把 Django 应用程序的所有配置放在这个新块中。 我们将首先指定此块应侦听普通端口 80,并应响应我们服务器的域名或 IP 地址:
server { listen 80; server_name server_domain_or_IP; }
接下来,我们将告诉 Nginx 忽略查找 favicon 的任何问题。 我们还将告诉它在哪里可以找到我们在 ~/myproject/static
目录中收集的静态资产。 所有这些文件都有一个标准的 URI 前缀“/static”,所以我们可以创建一个位置块来匹配这些请求:
server { listen 80; server_name server_domain_or_IP; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /home/user/myproject; } }
最后,我们将创建一个 location / {}
块来匹配所有其他请求。 在这个位置内部,我们将设置一些标准的代理 HTTP 标头,以便 Gunicorn 可以获得有关远程客户端连接的一些信息。 然后我们将流量传递到我们在 Gunicorn Systemd 单元文件中指定的套接字:
server { listen 80; server_name server_domain_or_IP; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /home/user/myproject; } location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://unix:/home/user/myproject/myproject.sock; } }
完成后保存并关闭文件。
调整组成员和权限
nginx
用户必须有权访问我们的应用程序目录,以便它可以提供静态文件、访问套接字文件等。 CentOS 非常严格地锁定每个用户的主目录,因此我们将 nginx
用户添加到我们的用户组,这样我们就可以打开使其运行所需的最低权限。
使用以下命令将 nginx
用户添加到您的组。 用您自己的用户名替换命令中的 user
:
sudo usermod -a -G user nginx
现在,我们可以授予用户组对主目录的执行权限。 这将允许 Nginx 进程输入和访问以下内容:
chmod 710 /home/user
设置好权限后,我们可以测试 Nginx 配置文件的语法错误:
sudo nginx -t
如果没有出现错误,请键入以下命令重新启动 Nginx 服务:
sudo systemctl start nginx
通过键入以下命令告诉 init 系统在启动时启动 Nginx 服务器:
sudo systemctl enable nginx
您现在应该可以通过服务器的域名或 IP 地址在浏览器中访问您的 Django 应用程序,而无需指定端口。
结论
在本指南中,我们在自己的虚拟环境中设置了一个 Django 项目。 我们已经配置 Gunicorn 来翻译客户端请求,以便 Django 可以处理它们。 之后,我们设置 Nginx 作为反向代理来处理客户端连接并根据客户端请求为正确的项目提供服务。
Django 通过提供许多通用部分使创建项目和应用程序变得简单,让您可以专注于独特的元素。 通过利用本文中描述的通用工具链,您可以轻松地为您从单个服务器创建的应用程序提供服务。