在Ubuntu 18.04上使用Postgres,Nginx和Gunicorn设置Django
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