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

介绍

Django是一个功能强大的Web框架,可以帮助您实现Python应用程序或网站。Django包含一个简化的开发服务器,用于在本地测试您的代码,但是对于任何与生产相关的细节,都需要一个更安全,更强大的Web服务器。

在本指南中,我们将演示如何在Ubuntu 18.04上安装和配置某些组件以支持和服务Django应用程序。我们将设置PostgreSQL数据库,而不是使用默认的SQLite数据库。我们将配置Gunicorn应用程序服务器以与我们的应用程序连接。然后,我们将设置Nginx以反向代理Gunicorn,让我们可以访问其安全性和性能功能来为我们的应用程序提供服务。

先决条件和目标

为了完成本指南,您应该拥有一个新的Ubuntu 18.04服务器实例,其中包含基本防火墙和配置了sudo权限的非root用户。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器。在您的服务器上启用防火墙,如果您使用的是腾讯云的CVM服务器,您可以直接在腾讯云控制台中的安全组进行设置。

我们将在虚拟环境中安装Django。将Django安装到特定于项目的环境中将允许单独处理您的项目及其需求。

一旦我们启动并运行了数据库和应用程序,我们将安装和配置Gunicorn应用程序服务器。这将作为我们应用程序的接口,将客户端请求从HTTP转换为我们的应用程序可以处理的Python调用。然后,我们将在Gunicorn面前设置Nginx,以利用其高性能连接处理机制及其易于实现的安全功能。

让我们开始吧。

从Ubuntu存储库安装软件包

要开始这个过程,我们将从Ubuntu存储库下载并安装我们需要的所有项目。稍后我们将使用Python包管理器pip安装其他组件。

我们需要更新本地apt包索引,然后下载并安装包。我们安装的软件包取决于您的项目将使用哪个版本的Python。

如果您在Python 3中使用Django ,请键入:

sudo apt update
sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl

Django 1.11是支持Python 2的Django的最后一个版本。如果你正在开始新项目,强烈建议你选择Python 3.如果你仍然需要使用Python 2,请输入:

sudo apt update
sudo apt install python-pip python-dev libpq-dev postgresql postgresql-contrib nginx curl

这将安装pip,后来构建Gunicorn所需的Python开发文件,Postgres数据库系统和与之交互所需的库,以及Nginx Web服务器。

创建PostgreSQL数据库和用户

我们将直接进入并为我们的Django应用程序创建数据库和数据库用户。

默认情况下,Postgres使用称为“对等身份验证”的身份验证方案进行本地连接。基本上,这意味着如果用户的操作系统用户名与有效的Postgres用户名匹配,则该用户无需进一步身份验证即可登录。

在Postgres安装期间,创建了一个名为postgres的操作系统用户,以对应postgresPostgreSQL管理用户。我们需要使用此用户来执行管理任务。我们可以使用sudo并使用-u选项传递用户名。

键入以下内容登录交互式Postgres会话:

sudo -u postgres psql

您将获得PostgreSQL提示,我们可以在其中设置我们的要求。

首先,为您的项目创建一个数据库:

CREATE DATABASE myproject;

注意:每个Postgres语句必须以分号结尾,因此如果遇到问题,请确保命令以1结尾。

接下来,为我们的项目创建一个数据库用户。确保选择安全密码:

CREATE USER myprojectuser WITH PASSWORD 'password';

之后,我们将为刚刚创建的用户修改一些连接参数。这将加速数据库操作,以便每次建立连接时都不必查询和设置正确的值。

我们正在将Django期望的默认编码设置为UTF-8。我们还将默认事务隔离方案设置为“read committed”,它阻止从未提交的事务中的读取。最后,我们正在设定时区。默认情况下,我们的Django项目将设置为使用UTC。以下是Django项目本身的所有建议:

ALTER ROLE myprojectuser SET client_encoding TO 'utf8';
ALTER ROLE myprojectuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE myprojectuser SET timezone TO 'UTC';

现在,我们可以为新用户提供管理新数据库的权限:

GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;

完成后,键入以下内容退出PostgreSQL提示符:

\q

现在设置了Postgres,以便Django可以连接并管理其数据库信息。

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

现在我们有了数据库,我们就可以开始准备其余的项目需求。我们将在虚拟环境中安装我们的Python需求,以便于管理。

为此,我们首先需要访问该virtualenv命令。我们可以使用pip来安装这个。

如果您使用的是Python 3,请键入以下命令升级pip并安装该软件包:

sudo -H pip3 install --upgrade pip
sudo -H pip3 install virtualenv

如果您使用的是Python 2,请键入以下命令升级pip并安装该软件包:

sudo -H pip install --upgrade pip
sudo -H pip install virtualenv

随着virtualenv安装,我们可以开始形成我们的项目。创建并移动到我们可以保存项目文件的目录中:

mkdir ~/myprojectdir
cd ~/myprojectdir

在项目目录中,键入以下命令创建Python虚拟环境:

virtualenv myprojectenv

这将在您的myprojectdir目录中创建一个名为myprojectenv的目录。在里面,它将安装本地版本的Python和pip的本地版本。我们可以使用它为我们的项目安装和配置一个独立的Python环境。

在我们安装项目的Python需求之前,我们需要激活虚拟环境。您可以通过键入以下内容来执

source myprojectenv/bin/activate

您的提示应更改为表明您现在在Python虚拟环境中运行。它看起来像这样:(myprojectenv)user@host:~/myprojectdir$

在您的虚拟环境处于活动状态时,使用以下pip本地实例来安装Django,Gunicorn和psycopg2PostgreSQL适配器:

注意:当虚拟环境被激活时(当您的提示位于其(myprojectenv)前面时),即使您使用的是Python3,也请使用pip而不是pip3. 无论Python是什么版本,虚拟环境的工具副本始终都会被命名为pip

pip install django gunicorn psycopg2-binary

您现在应该拥有启动Django项目所需的所有软件。

创建和配置新的Django项目

安装我们的Python组件后,我们可以创建实际的Django项目文件。

创建Django项目

由于我们已经有了一个项目目录,我们将告诉Django在这里安装文件。它将使用实际代码创建第二级目录,这是正常的,并将管理脚本放在此目录中。关键是我们明确定义目录,而不是允许Django相对于我们当前目录做出决定:

django-admin.py startproject myproject ~/myprojectdir

此时,您的项目目录(在我们的示例中为~/myprojectdir)应具有以下内容:

  • ~/myprojectdir/manage.py:Django项目管理脚本。
  • ~/myprojectdir/myproject/:Django项目包。这应该包括__init__.pysettings.pyurls.py,和wsgi.py文件。
  • ~/myprojectdir/myprojectenv/:我们之前创建的虚拟环境目录。

调整项目设置

我们应该对新创建的项目文件做的第一件事就是调整设置。在文本编辑器中打开设置文件:

nano ~/myprojectdir/myproject/settings.py

首先找到ALLOWED_HOSTS指令。这定义了服务器的地址列表或可用于连接Django实例的域名。具有不在此列表中的主机头的任何传入请求都将引发异常。Django要求您将其设置为防止某类安全漏洞。

在方括号中,列出与Django服务器关联的IP地址或域名。每个项目都应该在引号中列出,条目用逗号分隔。如果您希望请求整个域和任何子域,请在条目的开头添加一个句点。在下面的代码段中,有一些注释掉的示例用于演示:

注意:确保包含localhost并将其作为选项之一,因为我们将通过本地Nginx实例代理连接。

. . .
# The simplest case: just add the domain name(s) and IP addresses of your Django server
# ALLOWED_HOSTS = [ 'example.com', '203.0.113.5']
# To respond to 'example.com' and any subdomains, start the domain with a dot
# ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . ., 'localhost']

接下来,找到配置数据库访问的部分。它将从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_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

完成后保存并关闭文件。

完成初始项目设置

现在,我们可以使用管理脚本将初始数据库模式迁移到PostgreSQL数据库:

~/myprojectdir/manage.py makemigrations
~/myprojectdir/manage.py migrate

键入以下内容为项目创建管理用户:

~/myprojectdir/manage.py createsuperuser

您必须选择用户名,提供电子邮件地址,然后选择并确认密码。

我们可以通过输入以下内容将所有静态内容收集到我们配置的目录位置:

~/myprojectdir/manage.py collectstatic

您必须确认操作。然后,静态文件将被放在项目目录中名为static的目录中。

如果您按照初始服务器设置指南进行操作,则应该使用UFW防火墙来保护您的服务器。为了测试开发服务器,我们必须允许访问我们将要使用的端口。

键入以下命令为端口8000创建例外:

sudo ufw allow 8000

最后,您可以使用以下命令启动Django开发服务器来测试我们的项目:

~/myprojectdir/manage.py runserver 0.0.0.0:8000

在Web浏览器中,访问后跟:8000的服务器的域名或IP地址:

http://server_domain_or_IP:8000

您应该看到默认的Django索引页面:

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

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

完成浏览后,在终端窗口中按CTRL-C关闭开发服务器。

测试Gunicorn服务项目的能力

在离开我们的虚拟环境之前,我们要做的最后一件事是测试Gunicorn以确保它可以为应用程序提供服务。我们可以通过输入项目目录并使用gunicorn来加载项目的WSGI模块来完成此操作:

cd ~/myprojectdir
gunicorn --bind 0.0.0.0:8000 myproject.wsgi

这将在运行Django开发服务器的同一界面上启动Gunicorn。您可以返回并再次测试应用程序。

注意:管理界面不会应用任何样式,因为Gunicorn不知道如何找到对此负责的静态CSS内容。

我们通过使用Python的模块语法指定Django的wsgi.py 文件的相对目录路径来传递Gunicorn模块,该文件是我们应用程序的入口点。在此文件内部,定义了一个名为application的函数,用于与应用程序通信。

完成测试后,在终端窗口中按CTRL-C以停止Gunicorn。

我们现在已经完成了Django应用程序的配置。我们可以通过输入以下命令退出虚拟环境:

deactivate

将删除提示中的虚拟环境指示器。

为Gunicorn创建系统的套接字和服务文件

我们已经测试过Gunicorn可以与我们的Django应用程序进行交互,但是我们应该实现一种更强大的启动和停止应用程序服务器的方法。为此,我们将制作systemd服务和套接字文件。

Gunicorn套接字将在启动时创建,并将监听连接。当发生连接时,systemd将自动启动Gunicorn进程来处理连接。

首先为Gunicorn创建并打开一个具有sudo权限的systemd套接字文件:

sudo nano /etc/systemd/system/gunicorn.socket

在里面,我们将创建一个描述套接字的[Unit]部分,一个定义套接字位置的[Socket]部分,以及一个确保在正确的时间创建套接字的[Install]部分:

[Unit]
Description=gunicorn socket
​
[Socket]
ListenStream=/run/gunicorn.sock
​
[Install]
WantedBy=sockets.target

完成后保存并关闭文件。

接下来,在文本编辑器中使用sudo权限为Gunicorn创建并打开systemd服务文件。服务文件名应与套接字文件名匹配,但扩展名除外:

sudo nano /etc/systemd/system/gunicorn.service

从该[Unit]部分开始,该部分用于指定元数据和依赖项。我们将在此处描述我们的服务,并告诉init系统仅在达到网络目标后启动它。因为我们的服务依赖于套接字文件中的套接字,所以我们需要包含一个Requires指令来指示这种关系:

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

接下来,我们将打开该[Service]部分。我们将指定要在其下运行的用户和组。我们将为该流程提供常规用户帐户所有权,因为它拥有所有相关文件。我们将为www-data小组提供团体所有权,以便Nginx可以轻松地与Gunicorn进行交流。

然后,我们将映射工作目录并指定用于启动服务的命令。在这种情况下,我们必须指定Gunicorn可执行文件的完整路径,该文件安装在我们的虚拟环境中。我们将进程绑定到我们在/run目录中创建的Unix套接字,以便进程可以与Nginx通信。我们将所有数据记录到标准输出,以便该journald过程可以收集Gunicorn日志。我们还可以在这里指定任何可选的Gunicorn调整。例如,在这种情况下我们指定了3个工作进程:

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

[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myprojectdir
ExecStart=/home/sammy/myprojectdir/myprojectenv/bin/gunicorn \
          --access-logfile - \
          --workers 3 \
          --bind unix:/run/gunicorn.sock \
          myproject.wsgi:application

最后,我们将添加一个[Install]部分。如果我们在启动时启动它,这将告诉systemd将此服务链接到什么。我们希望在常规多用户系统启动并运行时启动此服务:

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

[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myprojectdir
ExecStart=/home/sammy/myprojectdir/myprojectenv/bin/gunicorn \
          --access-logfile - \
          --workers 3 \
          --bind unix:/run/gunicorn.sock \
          myproject.wsgi:application

[Install]
WantedBy=multi-user.target

这样,我们的systemd服务文件就完成了。立即保存并关闭它。

我们现在可以启动并启用Gunicorn套接字。这将在现在和启动时在/run/gunicorn.sock中创建套接字文件。当连接到该套接字时,systemd将自动启动gunicorn.service来处理它:

sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket

我们可以通过检查套接字文件来确认操作是否成功。

检查Gunicorn套接字文件

检查进程的状态以确定它是否能够启动:

sudo systemctl status gunicorn.socket

接下来,检查/run目录中是否存在该gunicorn.sock文件:

file /run/gunicorn.sock
Output/run/gunicorn.sock: socket

如果systemctl status命令指示发生错误或者您在目录中找不到该gunicorn.sock文件,则表明无法正确创建Gunicorn套接字。输入以下内容检查Gunicorn套接字的日志:

sudo journalctl -u gunicorn.socket

再继续查看您的/etc/systemd/system/gunicorn.socket文件以解决任何问题。

测试套接字激活

目前,如果您只启动了该gunicorn.socket单元,则由于套接字尚未收到任何连接,因此gunicorn.service将不会处于活动状态。您可以输入以下命令来检查:

sudo systemctl status gunicorn
● gunicorn.service - gunicorn daemon
   Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
   Active: inactive (dead)

要测试套接字激活机制,我们可以通过curl来键入以下内容来发送连接到套接字:

curl --unix-socket /run/gunicorn.sock localhost

您应该在终端中看到应用程序的HTML输出。这表明Gunicorn已经启动并能够为您的Django应用程序提供服务。您可以通过键入以下内容来验证Gunicorn服务是否正在运行:

sudo systemctl status gunicorn
● gunicorn.service - gunicorn daemon
   Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
   Active: active (running) since Mon 2018-07-09 20:00:40 UTC; 4s ago
 Main PID: 1157 (gunicorn)
    Tasks: 4 (limit: 1153)
   CGroup: /system.slice/gunicorn.service
           ├─1157 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
           ├─1178 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
           ├─1180 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
           └─1181 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application

Jul 09 20:00:40 django1 systemd[1]: Started gunicorn daemon.
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Starting gunicorn 19.9.0
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Listening at: unix:/run/gunicorn.sock (1157)
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Using worker: sync
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1178] [INFO] Booting worker with pid: 1178
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1180] [INFO] Booting worker with pid: 1180
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1181] [INFO] Booting worker with pid: 1181
Jul 09 20:00:41 django1 gunicorn[1157]:  - - [09/Jul/2018:20:00:41 +0000] "GET / HTTP/1.1" 200 16348 "-" "curl/7.58.0"

如果输出curl或输出systemctl status,则说明出现问题,请检查日志以获取其他详细信息:

sudo journalctl -u gunicorn

检查/etc/systemd/system/gunicorn.service文件是否存在问题。如果您对/etc/systemd/system/gunicorn.service文件进行了更改,请重新加载守护程序以重新读取服务定义并通过键入以下内容重新启动Gunicorn进程:

sudo systemctl daemon-reload
sudo systemctl restart gunicorn

请确保在继续之前解决上述问题。

将Nginx配置为代理传递给Gunicorn

现在Gunicorn已经建立,我们需要配置Nginx以将流量传递给进程。

首先在Nginx的sites-available目录中创建并打开一个新的服务器块:

sudo nano /etc/nginx/sites-available/myproject

在里面,打开一个新的服务器块。我们将首先指定此块应该侦听正常端口80,并且它应该响应我们服务器的域名或IP地址:

server {
    listen 80;
    server_name server_domain_or_IP;
}

接下来,我们将告诉Nginx忽略找到图标的任何问题。我们还将告诉它在哪里可以找到我们在~/myprojectdir/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/sammy/myprojectdir;
    }
}

最后,我们将创建一个location / {}块来匹配所有其他请求。在这个位置的内部,我们将包含Nginx安装中包含的标准proxy_params文件,然后我们将流量直接传递给Gunicorn套接字:

server {
    listen 80;
    server_name server_domain_or_IP;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/sammy/myprojectdir;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }
}

完成后保存并关闭文件。现在,我们可以通过将文件链接到sites-enabled目录来启用该文件:

sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled

键入以下内容测试您的Nginx配置是否存在语法错误:

sudo nginx -t

如果没有报告错误,请输入以下命令重新启动Nginx:

sudo systemctl restart nginx

最后,我们需要在端口80上打开正常流量的防火墙。由于我们不再需要访问开发服务器,我们也可以删除规则以打开端口8000:

sudo ufw delete allow 8000
sudo ufw allow 'Nginx Full'

您现在应该可以转到服务器的域或IP地址来查看您的应用程序。

注意:配置Nginx后,下一步应该是使用SSL / TLS保护服务器的流量。这很重要,因为没有它,所有信息(包括密码)都以纯文本形式通过网络发送。

如果你有域名,保护你网站的最简单方法是使用腾讯云SSL证书服务,它提供免费的可信证书。腾讯云SSL证书安装操作指南进行设置。

如果你没有域名,建议您先去这里注册一个域名,您需要将域名解析到您的服务器,您可以使用腾讯云云解析进行快速设置。

对Nginx和Gunicorn进行故障排除

如果最后一步未显示您的应用程序,则需要对安装进行故障排除。

Nginx显示默认页面而不是Django应用程序

如果Nginx的显示默认页,而不是代理到您的应用程序,它通常意味着你需要调整 /etc/nginx/sites-available/myproject 文件中的 ,以指向您的服务器的IP地址或域名。

Nginx使用server_name 来确定用于响应请求的服务器块。如果您看到默认的Nginx页面,则表明Nginx无法明确地将请求与服务器块匹配,因此它将回退到定义在/etc/nginx/sites-available/default中的默认块。

在您的项目的服务器块中的server_name必须更加具体的,而不是被选择一个默认的服务器模块。

Nginx显示502 Bad Gateway错误而不是Django应用程序

502错误表示Nginx无法成功代理请求。各种配置问题都表现为502错误,因此需要更多信息才能正确排除故障。

查找更多信息的主要位置是Nginx的错误日志。通常,这将告诉您在代理事件期间导致问题的条件。键入以下内容,遵循Nginx错误日志:

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

现在,在浏览器中发出另一个请求以生成新的错误(尝试刷新页面)。您应该看到写入日志的新错误消息。如果您查看该消息,它应该可以帮助您缩小问题范围。

您可能会看到以下消息:

connect()到unix:/run/gunicorn.sock失败(2:没有这样的文件或目录)

这表明Nginx无法在给定位置找到该gunicorn.sock文件。您应该将在/etc/nginx/sites-available/myproject文件中定义的proxy_pass位置与gunicorn.socketsystemd单元生成的gunicorn.sock文件的实际位置进行比较。

如果在/run目录中找不到gunicorn.sock文件,通常意味着systemd套接字文件无法创建它。返回检查Gunicorn套接字文件的部分,逐步完成Gunicorn的故障排除步骤。

connect()到unix:/run/gunicorn.sock失败(13:权限被拒绝)

这表明由于权限问题,Nginx无法连接到Gunicorn套接字。使用root用户而不是sudo用户执行该过程时,可能会发生这种情况。虽然systemd能够创建Gunicorn套接字文件,但Nginx无法访问它。

如果根目录(/)和gunicorn.sock文件之间的任何点上的权限有限,则会发生这种情况。我们可以通过将socket文件的绝对路径传递给namei命令来查看套接字文件及其每个父目录的权限和所有权值:

namei -l /run/gunicorn.sock
Outputf: /run/gunicorn.sock
drwxr-xr-x root root /
drwxr-xr-x root root run
srw-rw-rw- root root gunicorn.sock

输出显示每个目录组件的权限。通过查看权限(第一列),所有者(第二列)和组所有者(第三列),我们可以确定允许哪种类型的访问套接字文件。

在上面的示例中,套接字文件和通向套接字文件的每个目录都具有全局读取和执行权限(目录的权限列以r-x而不是---)结束。Nginx进程应该能够成功访问套接字。

如果通向套接字的任何目录没有全局读取和执行权限,则Nginx将无法在不允许全局读取和执行权限的情况下访问套接字,或确保将组所有权授予Nginx所属的组的。

Django显示:“无法连接到服务器:连接被拒绝”

尝试在Web浏览器中访问应用程序的某些部分时,您可能会从Django看到的一条消息是:

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

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

进一步排除故

对于其他故障排除,日志可以帮助缩小根本原因。依次检查每一个并查找指示问题区域的消息。

以下日志可能会有所帮助:

  • 键入以下命令检查Nginx进程日志: sudo journalctl -u nginx
  • 键入以下命令检查Nginx访问日志: sudo less /var/log/nginx/access.log
  • 键入以下命令检查Nginx错误日志: sudo less /var/log/nginx/error.log
  • 键入以下命令检查Gunicorn应用程序日志: sudo journalctl -u gunicorn
  • 键入以下命令检查Gunicorn套接字日志: sudo journalctl -u gunicorn.socket

在更新配置或应用程序时,可能需要重新启动进程以根据更改进行调整。

如果您更新Django应用程序,可以通过键入以下命令重新启动Gunicorn进程以获取更改:

sudo systemctl restart gunicorn

如果您更改了Gunicorn套接字或服务文件,请重新加载守护程序并通过键入以下内容重新启动该过程:

sudo systemctl daemon-reload
sudo systemctl restart gunicorn.socket gunicorn.service

如果您更改Nginx服务器块配置,请通过键入以下内容来测试配置,然后测试Nginx:

sudo nginx -t && sudo systemctl restart nginx

这些命令有助于在调整配置时获取更改。

结论

在本指南中,我们在自己的虚拟环境中设置了一个Django项目。我们已经配置了Gunicorn来翻译客户端请求,以便Django可以处理它们。之后,我们设置Nginx作为反向代理来处理客户端连接并根据客户端请求提供正确的项目。

Django通过提供许多常见的部分使创建项目和应用程序变得简单,使您可以专注于独特的元素。通过利用本文中介绍的常规工具链,您可以轻松地为从单个服务器创建的应用程序提供服务。

更多Ubuntu教程请前往腾讯云+社区学习更多知识。


参考文献:《How To Set Up Django with Postgres, Nginx, and Gunicorn on Ubuntu 18.04》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云计算教程系列

如何使用Apache驱动Django

Django是一个功能强大的Web框架,可以帮助您快速启动Python应用程序或网站。Django包含一个简化的开发服务器,用于在本地测试您的代码。但是其也需要...

3105
来自专栏yukong的小专栏

基于SpringCloud Finchley.SR1 、Spring Oauth2 SpringBoot 2.x、 vue、element-ui 微服务基础脚手架

github 地址 跪求大家star panda微服务工程地址 panda-admin前台工程地址

5913
来自专栏学一学大数据

一文上手zabbix安装配置【运维篇】

2003
来自专栏电光石火

eclipse配置tomcat运行时访问路径不要项目名称

1:双击打开tomcat 2:选择Modules,选择你要修改的项目 ? 3:点击Edit,把path修改成空或者你自己想要的路径即可! ?

3126
来自专栏云计算教程系列

如何在Ubuntu 16.04上使用Apache和mod_wsgi为Django应用程序提供服务

Django是一个功能强大的Web框架,可以帮助您快速启动Python应用程序或网站。Django包含一个简化的开发服务器,用于在本地测试您的代码,但是对于任何...

1530
来自专栏程序员互动联盟

【编程基础】linux常用命令介绍(一)

系统信息 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 dmidecod...

41811
来自专栏云计算教程系列

如何在CentOS 7上使用Postgres,Nginx和Gunicorn设置Django

Django是一个功能强大的Web框架,可以帮助您启动Python应用程序或网站。Django包含一个简化的开发服务器,用于在本地测试您的代码,但是对于任何与生...

1633
来自专栏Brian

Install Django Nginx uWSGI

概述 最近项目需要安装和配置多站点环境,所以把多站点开发环境配置和安装记录下来,帮助其他人少走坑。 安装Python 2.7.x 首先安装一些开发环境基本的包和...

3979
来自专栏北京马哥教育

汇总:Linux文件管理的50个命令

文 | 糖豆 图 | 来源网络 糖豆贴心提醒,本文阅读时间6分钟,文末有秘密! Linux cat命令 cat 命令用于连接文件并打印到标准输出设备上...

5146
来自专栏云计算教程系列

如何在Debian 9上安装Apache Tomcat 9

Apache Tomcat是一个Web服务器和servlet容器,用于为Java应用程序提供服务。Tomcat是Apache Software Foundati...

5334

扫码关注云+社区

领取腾讯云代金券