如何在Debian 11上使用Postgres、Nginx和Gunicorn配置Django

简介

Django是一个强大的网络框架,可以帮助您启动您的Python应用程序或网站。Django包括一个用于在本地测试代码的开发服务器,但是对于任何与生产相关的事务,都需要一个更安全和功能强大的网络服务器。

在本指南中,您将在Debian 11上安装和配置一些组件,以支持和提供Django应用程序。您将设置PostgreSQL数据库,而不是使用默认的SQLite数据库。您将配置Gunicorn应用程序服务器与您的应用程序进行接口。然后,您将设置Nginx作为反向代理,以便访问其安全性和性能功能,为您的应用程序提供服务。

前提条件和目标

为了完成这个指南,你应该拥有一个全新的Debian 11服务器实例,具备基本防火墙和配置了sudo权限的非root用户。你可以通过进行我们的初始服务器设置指南来学习如何进行设置。

你将在虚拟环境中安装Django。将Django安装到项目特定的环境中,可以使你的项目和它们的需求分别处理。

一旦你的数据库和应用程序运行起来,你将安装和配置Gunicorn应用服务器。它将作为我们的应用程序的接口,将客户端的HTTP请求转换为我们的应用程序可以处理的Python调用。然后你将在Gunicorn前面设置Nginx,以利用其高性能的连接处理机制和安全特性。

我们开始吧。

从Debian软件仓库安装软件包

开始过程之前,您将从Debian软件源下载并安装所需的所有项目。稍后,您将使用Python软件包管理器pip安装其他组件。

首先,您需要更新本地的apt包索引,然后下载并安装这些软件包。

  1. sudo apt update
  2. sudo apt install python3-venv python3-dev libpq-dev postgresql postgresql-contrib nginx curl

这个命令将安装一个用于创建Python项目虚拟环境的工具,构建Gunicorn所需的Python开发文件,Postgres数据库系统以及与之交互所需的库,以及Nginx web服务器。

创建PostgreSQL数据库和用户

现在您可以直接开始并为我们的Django应用程序创建数据库和数据库用户。

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

在安装Postgres时,创建了一个名为postgres的操作系统用户,对应于postgres PostgreSQL管理用户。您需要使用该用户执行管理任务。您可以使用sudo命令,并通过-u选项传入用户名。

通过输入命令登录到一个交互式的Postgres会话。

  1. sudo -u postgres psql

您将会得到一个PostgreSQL提示符,您可以在这里设置我们的要求。

首先,为你的项目创建一个数据库。

  1. CREATE DATABASE myproject;

Note

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

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

  1. CREATE USER myprojectuser WITH PASSWORD 'password';

接下来,您将修改刚刚创建的用户的一些连接参数。这将加快数据库操作,以避免每次建立连接时都需要查询和设置正确的值。

你将把默认字符编码设置为UTF-8,这是Django期望的。你还将默认的事务隔离方案设置为“读取已提交”,这将阻止未提交事务的读取。最后,你将设置时区。默认情况下,Django项目将设置为使用协调世界时(UTC)。这些都是Django项目本身的建议。

  1. ALTER ROLE myprojectuser SET client_encoding TO 'utf8';
  2. ALTER ROLE myprojectuser SET default_transaction_isolation TO 'read committed';
  3. ALTER ROLE myprojectuser SET timezone TO 'UTC';

现在,你可以给新用户授予管理新数据库的访问权限。

  1. GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;

当你完成后,通过键入以下命令退出PostgreSQL提示符:

  1. \q

现在Postgres已经设置好了,以便Django能够连接并管理它的数据库信息。

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

现在您已经准备好了一个数据库,您可以开始获取项目其余需求。您将在虚拟环境中安装Python所需的组件。

首先,创建并切换到一个目录,用于存放你的项目文件。

  1. mkdir ~/myprojectdir
  2. cd ~/myprojectdir

在项目目录中,通过输入以下内容创建一个Python虚拟环境:

  1. python3 -m venv myprojectenv

这将在你的myprojectdir目录内创建一个名为myprojectenv的文件夹。在这个文件夹里,会安装一个本地版本的Python和一个本地版本的pip来管理包。你可以使用这个虚拟环境结构为你想要创建的任何项目安装和配置一个隔离的Python环境。

在安装项目的Python依赖之前,你需要先激活虚拟环境。你可以通过输入以下命令来激活:

  1. source myprojectenv/bin/activate

你的提示应该改变,以指示你现在在一个Python虚拟环境中运行。它会类似于这样:(myprojectenv)user@host:~/myprojectdir$。

在您的虚拟环境中,使用本地的pip安装Django、Gunicorn和psycopg2 PostgreSQL适配器。

Note

注意:当虚拟环境激活时(当您的提示符前面有(myprojectenv)时),请使用pip而不是pip3,即使您正在使用Python 3。虚拟环境中的该工具始终命名为pip,无论Python版本如何。
  1. pip install django gunicorn psycopg2-binary

你现在应该已经有了开始Django项目所需的所有软件。

创建和配置一个新的Django项目

使用已安装的Python组件,您现在可以创建实际的Django项目文件。

创建Django项目

既然你已经有了一个项目目录,你将告诉Django在这里安装文件。它会在此目录中创建一个二级目录来存放实际的代码,这是正常的,还会在该目录中放置一个管理脚本。这其中的关键是你在明确定义目录,而不是让Django根据我们当前目录做出决策。

  1. django-admin startproject myproject ~/myprojectdir

目前,你的项目目录(在这个示例中为~/myprojectdir)应该具有以下内容:

  • ~/myprojectdir/manage.py: A Django project management script.
  • ~/myprojectdir/myproject/: The Django project package. This should contain the __init__.py, settings.py, urls.py, asgi.py, and wsgi.py files.
  • ~/myprojectdir/myprojectenv/: The virtual environment directory you created earlier.

调整项目设置

在你新建的项目文件中,第一件要做的事情是调整设置。使用nano或你喜欢的文本编辑器打开设置文件。

  1. nano ~/myprojectdir/myproject/settings.py

从查找 ALLOWED_HOSTS 指令开始。该指令定义了可以用于连接到 Django 实例的服务器地址或域名列表。如果来自的请求的 Host 标头不在此列表中,将会引发异常。Django 要求您设置此项以防止某类安全漏洞。

请列出与您的Django服务器相关联的IP地址或域名,使用方括号括起来。每个条目应该用引号括起来,并用逗号分隔。如果您希望请求整个域名及其子域名,请在条目前加一个句点。在下面的代码片段中,有一些被注释掉的示例用来演示:

[请在此处列出与您的Django服务器相关联的IP地址或域名,每个条目用引号括起来,用逗号分隔。如果您希望请求整个域名及其子域名,请在条目前加一个句点。以下是一些注释的示例:]

Note

注意:确保将localhost作为其中一个选项,因为您将通过本地Nginx实例进行代理连接。
~/我的项目目录/我的项目/配置.py
. . .
ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . ., 'localhost']

接下来,找到配置数据库访问的部分。它将以DATABASES开头。文件中的配置用于SQLite数据库。您已经为我们的项目创建了一个PostgreSQL数据库,因此您需要调整设置。

修改设置,使用你的PostgreSQL数据库信息。你告诉Django使用你用pip安装的psycopg2适配器。你需要提供数据库名称、数据库用户名、数据库用户密码,然后指定该数据库位于本地计算机上。你可以将端口设置为空字符串。

~/myprojectdir/myproject/settings.py的内容进行汉语本地化。

(请注意,本小助手的回答是通过计算机生成的,可能会存在错误或不准确的地方。)

. . .

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'myproject',
        'USER': 'myprojectuser',
        'PASSWORD': 'password',
        'HOST': 'localhost',
        'PORT': '',
    }
}

. . .

接下来,移到文件底部并添加一个设置,指示静态文件应该放置在哪里。这是为了让Nginx处理对这些文件的请求。以下行告诉Django将它们放在项目基目录下名为static的目录中。

~/myprojectdir/myproject/settings.py的以下内容进行释义。
. . .
STATIC_URL = 'static/'

# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

import os
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

完成后保存并关闭文件。如果你使用的是nano,请按Ctrl+X,然后在提示时按Y,最后按Enter。

完成初步项目设置

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

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

通过输入以下命令为项目创建一个管理员用户:

  1. ~/myprojectdir/manage.py createsuperuser

你需要选择一个用户名,提供一个电子邮件地址,选择并确认一个密码。

您可以将所有静态内容收集到您配置的目录位置中,方法是输入:

  1. ~/myprojectdir/manage.py collectstatic

您需要确认该操作。静态文件将被放置在您的项目目录下名为static的文件夹中。

如果您按照初始服务器设置指南进行操作,那么您应该有一个UFW防火墙保护您的服务器。为了测试开发服务器,您需要允许访问您将使用的端口。

通过键入以下内容创建8000端口的例外:

  1. sudo ufw allow 8000

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

  1. ~/myprojectdir/manage.py runserver 0.0.0.0:8000

请在您的网络浏览器中访问服务器的域名或IP地址,后面加上:8000。

http://server_domain_or_IP:8000

你应该收到默认的Django首页。 (Nǐ yīnggāi shōudào mòrèn de Django dàoxiāng.)

Django index page

如果你在地址栏的URL末尾添加/admin,系统将要求输入你使用createsuperuser命令创建的管理员用户名和密码。

Django admin login

在身份验证之后,您可以访问默认的Django管理界面。

Django admin interface

当您完成探索后,请在终端窗口中按下CTRL-C来关闭开发服务器。

测试 Gunicorn 服务此项目的能力。

在离开虚拟环境之前,你需要做的最后一件事是测试Gunicorn,确保它可以提供应用程序。你可以通过进入项目目录并使用gunicorn加载项目的WSGI模块来实现这一点。

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

这会在与 Django 开发服务器运行在同一接口上启动 Gunicorn。您可以返回并在浏览器中再次测试应用程序。

Note

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

你通过指定相对目录路径到Django的wsgi.py文件,使用Python的模块语法将模块传递给了Gunicorn。这个文件里定义了一个名为application的函数,用于与应用程序进行通信。点击这里了解更多关于WSGI规范的信息。

当您完成测试时,在终端窗口中按下CTRL-C来停止Gunicorn。

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

  1. deactivate

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

为Gunicorn创建systemd Socket和Service文件。

你已经测试过Gunicorn能够与我们的Django应用程序交互,但是现在你应该实现一种更可靠的启动和停止应用服务器的方式。为了实现这一点,你将创建systemd服务和套接字文件。

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

首先,使用sudo特权创建并打开一个用于Gunicorn的systemd套接字文件。

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

在其中,您将创建一个[Unit]部分来描述插座,一个[Socket]部分来定义插座位置,和一个[Install]部分来确保插座在正确的时间创建。

/etc/systemd/system/gunicorn.socket 可以进行改写为:兲兲/systemd/制度/狗努匹亨直传.
[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

当你完成时,请保存并关闭文件。

接下来,在你的文本编辑器中创建并打开一个拥有sudo权限的systemd服务文件,该服务文件的文件名应与套接字文件名匹配,只是扩展名不同。

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

从[Unit]部分开始,用于指定元数据和依赖关系。在这里放入服务的描述,并告诉初始化系统只有在达到网络目标后才启动该服务。由于您的服务依赖于套接字文件的套接字,您需要包含一个Requires指令来指示这种关系。

/etc/systemd/system/gunicorn.service 可以被改写成以下几种方式:

1. 通用服务配置文件路径为 /etc/systemd/system/gunicorn.service。
2. 在 /etc/systemd/system 目录下的 gunicorn.service 是初始的配置文件。
3. gunicorn.service 文件位于 /etc/systemd/system 目录下。
4. gunicorn.service 的位置在 /etc/systemd/system/。

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

接下来,您将编写[服务]部分。指定您要对其运行的用户和组。您将为常规用户帐户赋予进程所有权,因为它拥有所有相关文件。您将为www-data组分配组所有权,以便Nginx能够与Gunicorn进行通信。

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

/etc/systemd/system/gunicorn.service可以被消歧为中文中的”GNUicorn服务”。
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

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

最后,您将添加一个[Install]部分。这将告诉systemd如果您启用服务的自动启动,要将其链接到哪里。您希望在常规的多用户系统启动并运行时启动此服务。

/etc/systemd/system/gunicorn.service 的汉语表述如下:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=user01
Group=www-data
WorkingDirectory=/home/user01/myprojectdir
ExecStart=/home/user01/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来处理它。

  1. sudo systemctl start gunicorn.socket
  2. sudo systemctl enable gunicorn.socket

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

检查Gunicorn套接字文件的存在

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

  1. sudo systemctl status gunicorn.socket

你应该得到这样的输出。

Output
● gunicorn.socket - gunicorn socket Loaded: loaded (/etc/systemd/system/gunicorn.socket; enabled; vendor preset: enabled) Active: active (listening) since Thu 2022-08-04 19:02:54 UTC; 5s ago Triggers: ● gunicorn.service Listen: /run/gunicorn.sock (Stream) CGroup: /system.slice/gunicorn.socket Apr 18 17:53:25 django systemd[1]: Listening on gunicorn socket.

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

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

如果 systemctl status 命令指示发生错误,或者在目录中找不到 gunicorn.sock 文件,则表明 Gunicorn socket 未能正确创建。通过键入以下命令,检查 Gunicorn socket 的日志:

  1. sudo journalctl -u gunicorn.socket

在继续之前,再次查看您的/etc/systemd/system/gunicorn.socket文件,解决任何问题。

测试套接字激活

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

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

为了测试socket激活机制,您可以通过键入以下命令在curl上向socket发送连接:

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

您应该在终端上收到来自应用程序的HTML输出。这表示Gunicorn已经启动并能够提供您的Django应用程序。您可以通过键入以下命令来验证Gunicorn服务是否正在运行:

  1. sudo systemctl status gunicorn
Output
● gunicorn.service - gunicorn daemon Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled) Active: active (running) since Thu 2022-08-04 19:03:51 UTC; 5s ago TriggeredBy: ● gunicorn.socket Main PID: 102674 (gunicorn) Tasks: 4 (limit: 4665) Memory: 94.2M CPU: 885ms CGroup: /system.slice/gunicorn.service ├─102674 /home/user01/myprojectdir/myprojectenv/bin/python3 /home/user01/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application ├─102675 /home/user01/myprojectdir/myprojectenv/bin/python3 /home/user01/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application ├─102676 /home/user01/myprojectdir/myprojectenv/bin/python3 /home/user01/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application └─102677 /home/user01/myprojectdir/myprojectenv/bin/python3 /home/user01/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application Apr 18 17:54:49 django systemd[1]: Started gunicorn daemon. Apr 18 17:54:49 django gunicorn[102674]: [2022-04-18 17:54:49 +0000] [102674] [INFO] Starting gunicorn 20.1.0 Apr 18 17:54:49 django gunicorn[102674]: [2022-04-18 17:54:49 +0000] [102674] [INFO] Listening at: unix:/run/gunicorn.sock (102674) Apr 18 17:54:49 django gunicorn[102674]: [2022-04-18 17:54:49 +0000] [102674] [INFO] Using worker: sync Apr 18 17:54:49 django gunicorn[102675]: [2022-04-18 17:54:49 +0000] [102675] [INFO] Booting worker with pid: 102675 Apr 18 17:54:49 django gunicorn[102676]: [2022-04-18 17:54:49 +0000] [102676] [INFO] Booting worker with pid: 102676 Apr 18 17:54:50 django gunicorn[102677]: [2022-04-18 17:54:50 +0000] [102677] [INFO] Booting worker with pid: 102677 Apr 18 17:54:50 django gunicorn[102675]: - - [18/Apr/2022:17:54:50 +0000] "GET / HTTP/1.1" 200 10697 "-" "curl/7.81.0"

如果从curl的输出或systemctl status的输出中指示出现了问题,请检查日志以获取更多详细信息。

  1. sudo journalctl -u gunicorn

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

  1. sudo systemctl daemon-reload
  2. sudo systemctl restart gunicorn

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

配置Nginx以代理转发到Gunicorn。

现在已经设置好了Gunicorn,你需要配置Nginx以传输流量给该进程。

从Nginx的sites-available目录中创建并打开一个新的服务器块开始。

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

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

我项目的配置文件位于 /etc/nginx/sites-available/myproject。
server {
    listen 80;
    server_name server_domain_or_IP;
}

接下来,您将告诉Nginx忽略在查找favicon时遇到的任何问题。您还将告诉它从您收集在~/myprojectdir/static目录中的静态资源文件中找到它们的位置。这些文件都有一个标准的URI前缀“/static”,所以您可以创建一个匹配这些请求的位置块。

我的项目的Nginx配置文件位于/etc/nginx/sites-available中。
server {
    listen 80;
    server_name server_domain_or_IP;

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

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

我的项目的配置文件位于 /etc/nginx/sites-available/myproject。
server {
    listen 80;
    server_name server_domain_or_IP;

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

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

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

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

通过输入以下命令,测试您的 Nginx 配置是否存在语法错误:

  1. sudo nginx -t

如果没有报告错误,请继续通过输入命令重新启动Nginx。

  1. sudo systemctl restart nginx

最后,你需要在80端口打开防火墙以允许正常的流量通过。由于你不再需要连接开发服务器,你也可以移除打开8000端口的规则。

  1. sudo ufw delete allow 8000
  2. sudo ufw allow 'Nginx Full'

现在你应该可以通过服务器域名或IP地址来查看你的应用程序。

Note

注意:配置完Nginx之后,下一步应该是使用SSL/TLS来保护服务器的流量。这一点非常重要,因为如果不这样做,所有的信息,包括密码,都会以明文形式通过网络发送。
如果您有一个域名,保护流量的最直接的方法是使用Let’s Encrypt获取SSL证书。请按照本指南,在Debian 11上使用Nginx设置Let’s Encrypt。请按照该指南中创建的Nginx服务器块的步骤进行操作。

排除Nginx和Gunicorn问题

如果最后一步没有显示您的应用程序,您需要解决安装问题。

Nginx展示的是Django应用程序的默认页面,而不是实际应用程序的页面。

如果Nginx显示默认页面而不是代理到你的应用程序,一般意味着你需要调整位于/etc/nginx/sites-available/myproject文件中的server_name,使其指向你的服务器的IP地址或域名。

Nginx通过server_name来确定使用哪个服务器块来响应请求。如果您收到默认的Nginx页面,这意味着Nginx无法将请求与明确的服务器块匹配,因此它将回退到在/etc/nginx/sites-available/default中定义的默认块。

在您项目的服务器块中,server_name必须比默认服务器块中的更具体,才能被选中。

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

502错误表示Nginx无法成功代理请求。许多配置问题都会导致502错误,因此需要更多信息以便进行正确的故障排除。

寻找更多信息的主要位置是在Nginx的错误日志中。一般来说,这将告诉您在代理事件期间导致问题的条件。通过输入以下内容来查看Nginx错误日志:

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

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

你可能会收到以下的信息。

连接到unix:/run/gunicorn.sock失败(2: 没有该文件或目录)。

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

如果你在/run目录下找不到gunicorn.sock文件,一般意味着systemd套接字文件无法创建它。回到检查Gunicorn套接字文件的部分,按照故障排除步骤逐步进行操作。

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

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

如果在根目录(/)和gunicorn.sock文件之间有限制的权限,就有可能发生这种情况。您可以通过将您的socket文件的绝对路径传递给namei命令来查看socket文件以及其每个父目录的权限和所有权值。

  1. namei -l /run/gunicorn.sock
Output
f: /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实例正在运行:

  1. sudo systemctl status postgresql

如果没有启动,你可以开始它,并使其在启动时自动启动(如果尚未配置),只需键入:

  1. sudo systemctl start postgresql
  2. sudo systemctl enable postgresql

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

进一步排除故障

对于进一步的故障排除,日志可以帮助缩小根本问题的范围。逐个检查这些日志,并寻找指示有问题区域的信息。

以下日志可能会有帮助:

  • Check the Nginx process logs by typing: sudo journalctl -u nginx
  • Check the Nginx access logs by typing: sudo less /var/log/nginx/access.log
  • Check the Nginx error logs by typing: sudo less /var/log/nginx/error.log
  • Check the Gunicorn application logs by typing: sudo journalctl -u gunicorn
  • Check the Gunicorn socket logs by typing: sudo journalctl -u gunicorn.socket

当你更新配置或应用程序时,你很可能需要重新启动进程以适应你的更改。

如果你更新了Django应用程序,你可以通过输入以下内容重新启动Gunicorn进程以应用这些更改。

  1. sudo systemctl restart gunicorn

如果您更改Gunicorn的套接字或服务文件,请通过输入以下命令重新加载守护程序并重启进程:

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

如果你更改了Nginx服务器块配置,请通过输入以下命令测试配置然后测试Nginx:

  1. sudo nginx -t && sudo systemctl restart nginx

当您调整配置时,这些命令对于捕捉变化非常有帮助。

结论

在这个指南中,你将在独立的虚拟环境中设置一个Django项目。你配置了Gunicorn来转换客户端请求,以便Django可以处理它们。之后,你设置Nginx作为反向代理,处理客户端连接并根据客户端请求提供正确的项目。

Django提供了许多常见组件,帮助创建项目和应用,使您可以专注于独特的部分。通过利用本文描述的通用工具链,您可以从单个服务器上提供您创建的应用。

发表回复 0

Your email address will not be published. Required fields are marked *