在Ubuntu 18.04上使用Postgres,Nginx和Gunicorn设置Django

时间:2020-02-23 14:33:06  来源:igfitidea点击:

Django是一个通用,强大,高效且不断发展的基于python的Web应用程序框架,您可以使用它来启动和运行Web应用程序。
这是一个流行的网络框架,通常带有用于本地测试代码的开发服务器。
如果您打算将您的应用程序推入生产环境,则将需要更强大和安全的Web服务器设置。

在本教程中,我们将带您以更有效,更灵活的方式专业部署和配置Django。
我们将在SQLite数据库的位置安装和配置PostgreSQL数据库,并集成将与应用程序交互的Gunicorn应用程序服务器。
稍后,我们将继续设置NGINX Web服务器,它将为Gunicorn服务器提供反向代理通道,从而为我们提供服务于应用程序所需的性能和安全性组件。

入门

首先,我们将更新我们的Ubuntu存储库

$sudo apt-get update

接下来,我们将为要配置的所有应用程序下载并安装必需的软件包。
这些将包括pip包管理器,PostgreSQL和Nginx。
如果您使用Python3运行Django,则语法为

$sudo apt-get install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx

如果您的系统运行Python2,则命令将为:

$sudo apt-get install python-pip python-dev libpq-dev postgresql postgresql-contrib nginx

该命令将安装pip软件包管理器,构建Gunicorn,Nginx Web服务器,Postgres数据库所需的所有必需的Python开发文件以及与数据库引擎进行交互所需的关键库。

成功安装所有必需的软件包之后,现在该为Django Web应用程序创建一个数据库和一个用户了

创建PostgreSQL数据库和数据库用户

现在,直接进入并创建数据库和Django应用程序的用户登录到Postgres并执行命令

$sudo -u postgres psql

您将进入输出显示的Postgres提示符

为您的项目创建一个数据库。
在这种情况下,数据库名称为"项目"。

postgres=# CREATE DATABASE project;

注意! PostgreSQL中的所有命令都必须以分号终止。

成功创建数据库后,为Django项目创建一个用户,并确保分配一个安全的密码。
在这种情况下,用户是projectuser

用您自己的强密码替换"密码"属性。

postgres=# CREATE USER projectuser WITH PASSWORD 'password';

为了确认Django的数据库连接设置参数,我们将执行以下操作:

  • 将默认编码设置为UTF-8
  • 将隔离方案设置为"读取已提交"值
  • 将时区设置为UTC

执行以下命令来满足设置要求

postgres=# ALTER ROLE projectuser SET client_encoding TO 'utf8';
postgres=# ALTER ROLE projectuser SET default_transaction_isolation TO 'read committed';
postgres=# ALTER ROLE projectuser SET timezone TO 'UTC';

现在,向新创建的用户授予数据库访问权限

postgres=# GRANT ALL PRIVILEGES ON DATABASE project TO projectuser;

现在您可以退出Postgres环境。

postgres=# \q

为您的Django项目创建Python虚拟环境

为了更轻松地管理我们的应用程序,我们将在虚拟环境中安装必需的Python必备软件。
但首先,请安装虚拟环境。
如果您的系统运行的是Python3,请通过执行以下命令来升级pip

$sudo -H pip3  install --upgrade pip

对于在Python2上运行的系统

$sudo -H pip install --upgrade pip

之后,使用pip安装虚拟环境

$sudo -H pip install virtualenv

有了我们的虚拟环境之后,我们现在将创建并迁移到其中

$mkdir ~/project
$cd ~/project

现在创建一个Python虚拟环境

virtualenv projectenv

这将在项目目录中创建一个名为projectenv的目录。

在安装Python要求之前,请激活虚拟环境

$source projectenv/bin/activate

注意提示如何更改为(projectenv)james @ ubuntu:~/project $

在虚拟环境处于活动状态的情况下,让我们使用pip安装Gunicorn,Django和Psycopg2 Postgres适配器。

$pip install django gunicorn psycopg2-binary

创建和配置新的Django项目

此时,我们将指示Django将项目文件安装在我们已经创建的项目目录中。
将在管理脚本旁边创建第二级目录。
为此,请执行以下命令。

$django-admin.py startproject project ~/project

我们的项目目录,在这种情况下,~/project应该具有以下内容

manage.py      -  Django’s Python management script
project             - directory containing Django’s project package
projectenv      - Virtual environment directory that was earlier created

调整项目文件配置

我们将打开设置文件

vim ~/project/settings.py

向下滚动并查找"允许的主机"属性。
在方括号内,指定服务器的IP地址,然后附加"本地主机"属性。

接下来,找到"数据库"部分。
调整设置以符合PostgreSQL数据库信息。
这包括数据库名称,用户名和用户密码。

接下来,向下滚动并指定静态文件的位置。
这很重要,因此Nginx可以无缝处理对这些项目的请求。
在下面的代码段中,静态文件将放置在名为" static"的目录中

保存并退出。

完成初始项目设置

现在让我们将数据库方案迁移到PostgreSQL数据库

~/project/manage.py makemigrations
~/project/manage.py migrate

接下来,我们将通过执行以下命令为Django项目创建一个超级用户

~/project/manage.py createsuperuser

系统将提示您输入用户名,电子邮件和密码,如下所示

成功创建超级用户后,我们现在可以将静态内容收集到目录位置中

~/project/manage.py collectstatic

这些静态文件将放置在项目文件夹中的" static"目录中。

为了测试开发服务器,我们将允许使用端口(在这种情况下为端口8000),该端口将用于通过Web浏览器访问应用程序。

要打开端口,我们将执行

sudo ufw allow 8000

最后,通过运行以下命令在虚拟环境中启动Django开发服务器:

~/project/manage.py runserver 0.0.0.0:8000

打开网络浏览器并访问服务器的地址

在这种情况下,我们服务器的地址是

https://38.76.11.180/

您应该可以看到以下Django的索引页面

现在,在URL末尾附加/admin进入登录页面。

https://38.76.11.180/admin

提供您在创建超级用户帐户时提供的凭据,然后点击"登录"

这将带我们进入Django的"管理"面板

现在,我们已经确认Django已启动并正在运行,让我们在终端上按" CTRL + C"以退出应用程序

确认Gunicorn有能力测试项目

在退出虚拟环境之前,让我们确认我们的Gunicorn应用服务器可以为Django服务。
仍在项目目录中时,让我们加载WSGI模块

gunicorn --bind 0.0.0.0:8000 project.wsgi

这会在运行Django服务器的相同接口和端口上启动Gunicorn。
您可以返回并确认Django应用程序正在Web浏览器上运行。

完成后,按CTRL + C停止应用程序并运行deactivate命令退出虚拟环境。

经过测试,Gunicorn应用程序服务器可以为我们的Django应用程序提供服务,是时候实现一种更强大的启动和停止应用程序服务器的途径了。
我们将使用以下命令使用Gunicorn创建一个systemd服务文件

$sudo vim /etc/systemd/system/gunicorn.service

从[Unit]部分开始,粘贴以下内容

[Unit]
Description=gunicorn daemon
After=network.target

本节指定依赖项和元数据

接下来,创建[service]部分。

在本节中,我们将指定进程应在其下运行的用户和组。
在这种情况下,用户为root,组为www-data。
该组被指定为www-data,以便Nginx可以与Gunicorn无缝通信。

然后将显示Gunicorn可执行文件的完整路径。
由于Nginx安装在同一服务器中,因此我们将其绑定到Unix套接字。

粘贴以下内容

[Service]
User=james
Group=www-data
WorkingDirectory=/home/james/project
ExecStart=/home/james/project/projectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/james/project/project.sock project.wsgi:application

最后,创建[Install]部分并添加以下行

[Install]
WantedBy=multi-user.target

大!现在我们的系统服务文件已完成。

保存并关闭文本编辑器。
重新启动Gunicorn服务,并使其在启动时启动

$sudo systemctl start gunicorn
$sudo systemctl enable gunicorn

检查gunicorn运行状态

$systemctl status gunicorn

验证是否存在Gunicorn套接字文件

既然我们已经验证了Nginx已经启动并正在运行,那么让我们验证项目目录中是否存在project.sock文件。

$ls -l /home/james/project

注意:

如果缺少project.sock文件,则表明gunicorn无法正确启动。
另外,您可以通过执行以下命令来检查Gunicorn日志

$sudo journalctl -u gunicorn

Nginx无法创建project.sock文件的原因有很多。
一些包括

  • 项目文件由root用户而非sudo用户拥有

  • /etc/systemd/system/gunicorn.service中的工作目录未指向项目目录。

  • ExecStart指令中的配置不正确

如果所有配置都可以,那么运行后应该不会出现任何错误

$sudo journalctl -u gunicorn

/etc/systemd/system/gunicorn.service文件进行更改后,请确保重新加载守护程序服务以使更改生效

$sudo systemctl daemon-reload

$sudo systemctl restart gunicorn

配置Nginx将流量定向到Gunicorn

本教程的最后一个阶段是配置Nginx Web服务器以将Web流量引导到Gunicorn服务

我们将在sites-available目录中创建并打开一个新的服务器块。

$sudo vim /etc/nginx/sites-available/project

首先指定此块应侦听端口80,并应响应服务器的IP地址。

server {
  listen 80;
  server_name server_domain_or_IP;
}

接下来,我们将指示Nginx忽略定位收藏夹的任何问题。
另外,我们将告诉它其中可以找到~/project/static目录中收集的静态资产。

location = /favicon.ico { access_log off; log_not_found off; }
  location /static/{
      root /home/james/project;
  }

最后,我们将创建一个匹配其余请求的块位置"/{}"。
在此位置,我们将定义proxy_params文件,然后将流量定向到Gunicorn进程创建的套接字

location/{
      include proxy_params;
      proxy_pass https://unix:/home/james/project/project.sock;
  }

最终配置文件应如下所示

保存并退出配置文件

通过将文件链接到启用站点的目录来启用文件

$sudo ln -s /etc/nginx/sites-available/project /etc/nginx/sites-enabled

接下来,让我们测试配置是否存在任何错误

$sudo nginx -t

如果一切顺利,输出应如下所示

测试Nginx配置后

$sudo systemctl restart nginx

现在,我们不再需要访问端口8000上的开发服务器,让我们删除防火墙上的规则。

$sudo ufw delete allow 8000

让我们也允许端口80

$sudo ufw allow 'Nginx Full'

现在,您无需指定端口8000即可访问服务器的域或者IP地址以查看您的应用程序

问题诊断

1.服务器显示默认的Nginx页面

如果Nginx显示默认页面而不是代理Django应用程序,则需要检查/etc/nginx/sites-available/project文件,并确保正确指示服务器的IP或者域名。
默认页面表示Nginx无法匹配您的请求,而是回退到/etc/nginx/sites-available/default

2. 502错误的网关错误,而不是Django应用程序

502错误表示Nginx Web服务器无法成功代理请求。
为了准确地解决问题,请检查错误日志文件中的日志,如下所示,这可以为您提供可能出了问题的线索。

$ sudo tail -F /var/log/nginx/error.log

3."无法连接到服务器"连接被拒绝

尝试访问Web浏览器中的某些特定组件时可能遇到的错误是

OperationalError at /admin/login/
could not connect to server: Connection refused
  Is the server running on host "localhost" (127.0.0.1) and accepting
  TCP/IP connections on port 5432?

这表明Django应用程序无法连接到Postgres数据库,通过执行以下命令确保Postgres正在运行

$sudo systemctl status postgresql

如果它没有运行,请启动它并使它能够在启动时启动

$sudo systemctl start postgresql
$sudo systemctl enable postgresql

如果仍然有问题,请确保~/myproject/myproject/settings.py中的数据库设置正确。

有关进一步的故障排除,请检查以下日志

Nginx process logs                 sudo journalctl -u nginx

Nginx access logs                    sudo tail -f  /var/log/nginx/access.log

Nginx error logs	          sudo less /var/log/nginx/error.log

Gunicorn Application logs     sudo journalctl -u gunicorn

更改配置文件时,请确保重新启动它们以使更改生效。

如果决定更改gunicorn systemd服务文件,请确保重新加载守护程序并重新启动gunicorn

$sudo systemctl daemon-reload
$sudo systemctl restart gunicorn

当您对Nginx服务器块配置进行更改时,请测试配置

$sudo nginx -t && sudo systemctl restart nginx