如何在 Ubuntu 20.04 上使用 Postgres、Nginx 和 Uvicorn 设置 ASGI Django 应用程序

介绍

Django是一个强大的Web框架,可以帮助您从地面上获得您的Python应用程序或网站。Django包括一个简化的开发服务器来本地测试您的代码,但需要一个更安全和更强大的Web服务器来制作相关的任何东西。

使用Web Server Gateway Interface(LINK0)(WSGI)部署Django应用的传统方法是使用Web Server Gateway Interface(WSGI)。然而,随着Python 3的出现和非同步执行的支持,您现在可以通过非同步调用来执行Python应用,使用Asynchronous Server Gateway Interface(LINK1)(ASGI)。

Django 允许一个非同步的外部,同步的内部模式,允许您的代码在内部同步,而 ASGI 服务器以非同步的方式处理请求. 通过允许 Web 服务器具有非同步的调用,它可以处理每个应用程序的多个进出和进出事件。 Django 应用程序仍然在内部同步,以允许反向兼容性和避免并行计算的复杂性。

在本指南中,您将安装和配置 Ubuntu 20.04 上的某些组件以支持和服务 Django 应用程序. 您将 设置 PostgreSQL 数据库而不是使用默认 SQLite 数据库。 您将配置与 Uvicorn 配对的 Gunicorn 应用程序服务器,这是一个 ASGI 实现程序,以与您的应用程序无同步交互。 然后,您将设置 Nginx 以向 Gunicorn 逆转代理,让您访问其安全性和性能功能来服务您的应用程序。

前提条件

要完成本教程,您将需要:

步骤 1 – 从 Ubuntu 存储库中安装包

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

首先,您需要更新本地apt包索引,然后下载和安装包. 您安装的包取决于您的项目将使用哪个Python版本。

使用以下命令来安装所需的系统包:

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

此命令将安装用于设置虚拟环境的 Python 库,Postgres 数据库系统和与其进行交互所需的库,以及 Nginx Web 服务器。

步骤 2 – 创建 PostgreSQL 数据库和用户

在此步骤中,您将为您的 Django 应用程序创建一个数据库和数据库用户。

默认情况下,Postgres 使用一个名为同行身份验证的身份验证方案,用于本地连接,这意味着如果用户的操作系统用户名匹配一个有效的 Postgres 用户名,则该用户可以无需进一步身份验证登录。

在 Postgres 安装过程中,一个名为postgres的操作系统用户被创建,以匹配postgreSQL的 PostgreSQL 管理用户。你需要使用这个用户来执行管理任务。

通过键入登录到一个互动的 Postgres 会话:

1sudo -u postgres psql

您将收到一个PostgreSQL提示,您可以设置要求。

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

1CREATE DATABASE myproject;

<$>[注] 注: 每个 Postgres 语句都必须以半字符号结束. 如果您遇到问题,请确保命令以半字符号结束。

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

1CREATE USER myprojectuser WITH PASSWORD 'password';

之后,您将更改您刚刚创建的用户的一些连接参数,从而加快数据库操作,以便每次建立连接时不需要查询和设置正确值。

您将默认编码设置为UTF-8,Django 预计。 您还将默认的交易隔离方案设置为读取承诺,即从未承诺的交易中读取块。 最后,您将设置时区。

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

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

1GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;

完成后,通过键入退出 PostgreSQL 提示:

1\q

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

步骤 3:为您的项目创建一个Python虚拟环境

现在你有一个数据库,你可以开始准备剩下的项目要求,你将安装你的Python要求在一个虚拟的环境中,以便更容易管理。

首先,创建并移动到一个目录,您可以保留您的项目文件:

1mkdir ~/myprojectdir
2cd ~/myprojectdir

然后使用Python内置的虚拟环境工具创建新的虚拟环境。

1python3 -m venv myprojectenv

这将创建一个名为myprojectenv的目录在你的myprojectdir目录中。内部,它将安装一个本地版本的Python和一个本地版本的pip

在安装项目的 Python 要求之前,您需要激活虚拟环境,您可以通过键入:

1source myprojectenv/bin/activate

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

您将在虚拟环境中安装 Django. 将 Django 安装到您项目的特定环境中,将允许您单独处理您的项目及其要求. 随着虚拟环境的活动,请安装 Django、Gunicorn、Uvicorn 以及具有本地实例的 PostgreSQL 适配器:

<$>[注] 注: 当虚拟环境被激活时(当您的提示有(myprojectenv)之前),使用pip而不是pip3,即使您正在使用Python 3. 虚拟环境的副本的工具总是被命名为pip,无论Python版本。

1pip install django gunicorn uvicorn psycopg2-binary

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

第4步:创建和配置一个新的Django项目

通过安装 Python 组件,您可以创建实际的 Django 项目文件。

创建 Django 项目

由于你已经有一个项目目录,你可以告诉Django在这里安装文件,它将创建一个与实际代码的第二级目录,这是正常的,并将管理脚本放入该目录。

1django-admin startproject myproject ~/myprojectdir

在此时,您的项目目录(~/myprojectdir在本教程中)应该有以下内容:

  • ~/myprojectdir/manage.py: 一个 Django 项目管理脚本.
  • ~/myprojectdir/myproject/: 该 Django 项目包. 这应该包含 __init__.py, asgi.py, settings.py, urls.pywsgi.py` 文件.
  • ~/myprojectdir/myprojectenv/: 您之前创建的虚拟环境目录.

调整项目设置

创建项目文件后,您需要调整一些设置。在文本编辑器中打开设置文件:

1nano ~/myprojectdir/myproject/settings.py

首先,找出ALLOWED_HOSTS指令,定义了可以用于连接到Django实例的服务器地址或域名列表,任何未列入此列表的 Host标题的输入请求都会引发例外。

在方块中,列出与您的 Django 服务器相关的 IP 地址或域名。列出每一个项目在引文中,其中有条纹分开的条目。 要允许一个完整的域名和任何子域名,请预先预设一个期限,以便开始输入。 在下面的片段中,有几个评论的例子用于展示如何做到这一点:

<$>[注] 注: 请确保将localhost列为选项之一,因为您将通过本地 Nginx 实例代理连接。

1[label ~/myprojectdir/myproject/settings.py]
2. . .
3# The simplest case: just add the domain name(s) and IP addresses of your Django server
4# ALLOWED_HOSTS = [ 'example.com', '203.0.113.5']
5# To respond to 'example.com' and any subdomains, start the domain with a dot
6# ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
7ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . ., 'localhost']

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

使用您的 PostgreSQL 数据库信息更改设置. 您会告诉 Django 使用您与pip安装的psycopg2适配器. 您需要输入数据库名称、数据库用户名称、数据库用户密码,然后指定数据库位于本地计算机上。

 1[label ~/myprojectdir/myproject/settings.py]
 2. . .
 3
 4DATABASES = {
 5    'default': {
 6        'ENGINE': 'django.db.backends.postgresql_psycopg2',
 7        'NAME': 'myproject',
 8        'USER': 'myprojectuser',
 9        'PASSWORD': 'password',
10        'HOST': 'localhost',
11        'PORT': '',
12    }
13}
14
15. . .

接下来,移动到文件的底部,并添加一个设置,表示 static 文件应该放置在哪里。 这是必要的,以便 Nginx 能够处理这些项目的请求。

1[label ~/myprojectdir/myproject/settings.py]
2. . .
3
4STATIC_URL = '/static/'
5import os
6STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

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

完成初步项目设置

现在,您可以使用管理脚本将初始数据库方案迁移到您的 PostgreSQL 数据库:

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

创建一个项目的管理用户,键入:

1~/myprojectdir/manage.py createsuperuser

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

您可以通过键入将所有静态内容收集到您配置的目录位置:

1~/myprojectdir/manage.py collectstatic

然后,静态文件将被放置在项目目录中的名为静态的目录中。

如果您遵循最初的服务器设置指南,您应该有一个 UFW 防火墙来保护您的服务器. 要测试开发服务器,您需要允许访问您正在使用的端口。

通过键入为端口 8000 创建例外:

1sudo ufw allow 8000

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

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

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

1http://server_domain_or_IP:8000

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

Django index page

如果您在地址栏中添加/admin到URL的末尾,您将被提示使用createsuperuser命令创建的管理用户名和密码:

Django admin login

验证后,您可以访问默认的 Django admin 界面:

Django admin interface

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

测试 Gunicorn 服务项目的能力

在本教程中,您将使用 Gunicorn 与 Uvicorn 配对来部署应用程序. 虽然 Gunicorn 传统上用于部署 WSGI 应用程序,但它还提供了一个可插入的界面来提供 ASGI 部署。 它通过允许您使用由 ASGI 服务器(uvicorn)暴露的工人阶级来实现这一点。 因为 Gunicorn 是一个更成熟的产品,提供比 Uvicorn 更多的配置, Uvicorn 维护者建议使用gunicornuvicorn工人阶级作为一个完整的服务器和流程管理器。

在离开虚拟环境之前,您将测试Gunicorn,以确保它可以服务于应用程序。

若要与gunicorn服务器使用uvicorn工人,请输入您的项目目录,并使用以下gunicorn命令加载项目的ASGI模块:

1cd ~/myprojectdir
2gunicorn --bind 0.0.0.0:8000 myproject.asgi -w 4 -k uvicorn.workers.UvicornWorker

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

<$>[注] 注: 您不需要使用 Gunicorn 来运行 ASGI 应用程序。

1uvicorn myproject.asgi:application --host 0.0.0.0 --port 8080

美元

<$>[注] **注:**管理员界面将不会有任何样式应用,因为Gunicorn不知道如何找到负责任的静态CSS内容。 <$> 如果Django欢迎页面仍然在启动这些命令后出现,这是确认gunicorn服务于页面并按预期工作。使用gunicorn命令,您通过指定Django的asgi.py文件的相对目录路径来传递给Gunicorn一个模块,这是您的应用程序的入口点,使用Python的模块语法。在这个文件中,一个名为application的函数被定义,用于与应用程序进行通信。 有关ASGI具体的更多信息,请访问 [官方ASGI网站]

当你完成测试时,在终端窗口中按CTRL+C来阻止Gunicorn。

您现在已经完成了配置您的 Django 应用程序,您可以通过键入退出虚拟环境:

1deactivate

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

步骤 5 — 创建 Gunicorn 的 systemd 接口和服务文件

在上一节中,您测试了 Gunicorn 是否可以与 Django 应用程序进行交互,在此步骤中,您将通过创建 systemd 服务和插件文件来实施更强大的启动和停止应用程序服务器的方式。

Gunicorn 接口将在启动时创建,并会听取连接。当发生连接时,systemd 会自动启动 Gunicorn 过程来处理连接。

首先,创建并打开有sudo特权的 Gunicorn 的 systemd 接口文件:

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

内部,您将创建一个[Unit]部分来描述插槽,一个[Socket]部分来定义插槽的位置,以及一个[Install]部分来确保插槽在正确的时间创建:

1[label /etc/systemd/system/gunicorn.socket]
2[Unit]
3Description=gunicorn socket
4
5[Socket]
6ListenStream=/run/gunicorn.sock
7
8[Install]
9WantedBy=sockets.target

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

接下来,在文本编辑器中创建并打开一个用sudo权限的 Gunicorn 的 systemd 服务文件,该服务的文件名应匹配扩展的 socket 文件名例外:

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

您将在这里列出您的服务的描述,并告诉 init 系统在实现网络目标后才启动此操作。由于该服务依赖于插件文件的插件,您需要包含一个要求指令来表示该关系:

1[label /etc/systemd/system/gunicorn.service]
2[Unit]
3Description=gunicorn daemon
4Requires=gunicorn.socket
5After=network.target

接下来,打开[服务]部分,您将指定您希望该过程运行的用户和组,您将给您的常规用户帐户所有权,因为它拥有所有相关的文件,您将给www-data组组所有权,以便 Nginx 可以轻松地与 Gunicorn 沟通。

然后,您将绘制工作目录并指定要使用的命令来启动服务. 在这种情况下,您将需要指定在虚拟环境中安装的Gunicorn可执行的完整路径。您将将过程绑定到您在/run目录中创建的Unix插件,以便该过程可以与Nginx进行通信。您将登录所有数据到标准输出,以便journald过程可以收集Gunicorn日志。

 1[label /etc/systemd/system/gunicorn.service]
 2[Unit]
 3Description=gunicorn daemon
 4Requires=gunicorn.socket
 5After=network.target
 6
 7[Service]
 8User=sammy
 9Group=www-data
10WorkingDirectory=/home/sammy/myprojectdir
11ExecStart=/home/sammy/myprojectdir/myprojectenv/bin/gunicorn \
12          --access-logfile - \
13          -k uvicorn.workers.UvicornWorker \
14          --workers 3 \
15          --bind unix:/run/gunicorn.sock \
16          myproject.asgi:application

最后,您将添加一个[安装]部分,这将告诉系统d如果您允许该服务在启动时启动,该服务将链接到什么。

 1[label /etc/systemd/system/gunicorn.service]
 2[Unit]
 3Description=gunicorn daemon
 4Requires=gunicorn.socket
 5After=network.target
 6
 7[Service]
 8User=sammy
 9Group=www-data
10WorkingDirectory=/home/sammy/myprojectdir
11ExecStart=/home/sammy/myprojectdir/myprojectenv/bin/gunicorn \
12          --access-logfile - \
13          -k uvicorn.workers.UvicornWorker \
14          --workers 3 \
15          --bind unix:/run/gunicorn.sock \
16          myproject.asgi:application
17
18[Install]
19WantedBy=multi-user.target

这样, systemd 服务文件就完成了. 现在保存并关闭它。

您现在可以启动并启用 Gunicorn 接口,这将创建在 /run/gunicorn.sock’ 和启动时的接口文件,当连接到该接口时,systemd 将自动启动 gunicorn.service’ 来处理它:

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

现在你已经完成了 systemd 服务和接口文件,你将通过检查接口文件来确认操作成功。

步骤 6 — 检查 Gunicorn 接口文件

在此步骤中,您将检查 Gunicorn 接口文件. 首先,检查过程的状态,以确定它是否能够启动:

1sudo systemctl status gunicorn.socket

结果将看起来像这样:

1[secondary_label Output]
2 gunicorn.socket - gunicorn socket
3     Loaded: loaded (/etc/systemd/system/gunicorn.socket; enabled; vendor prese>
4     Active: active (listening) since Fri 2020-06-26 17:53:10 UTC; 14s ago
5   Triggers:  gunicorn.service
6     Listen: /run/gunicorn.sock (Stream)
7      Tasks: 0 (limit: 1137)
8     Memory: 0B
9     CGroup: /system.slice/gunicorn.socket

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

1file /run/gunicorn.sock
1[secondary_label Output]
2/run/gunicorn.sock: socket

如果systemctl status命令显示出现错误,或者您在目录中找不到gunicorn.sock文件,则表示 Gunicorn 接口未正确创建。

1sudo journalctl -u gunicorn.socket

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

步骤 7 – 测试 Socket 激活

在此步骤中,您将测试插件的激活。当前,如果您刚刚启动了gunicorn.socket单元,则gunicorn.service将不会被激活,因为插件尚未接收任何连接。

1sudo systemctl status gunicorn
1[secondary_label Output]
2 gunicorn.service - gunicorn daemon
3   Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
4   Active: inactive (dead)

要测试插槽激活机制,您可以通过键入弯曲发送连接到插槽:

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

您应该从终端中收到您的应用程序的HTML输出。这表明Gunicorn已经启动并能够服务您的Django应用程序。您可以通过键入来验证Gunicorn服务正在运行:

1sudo systemctl status gunicorn
 1[secondary_label Output]
 2
 3 gunicorn.service - gunicorn daemon
 4     Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
 5     Active: active (running) since Thu 2021-06-10 21:03:29 UTC; 13s ago
 6TriggeredBy:  gunicorn.socket
 7   Main PID: 11682 (gunicorn)
 8      Tasks: 4 (limit: 4682)
 9     Memory: 98.5M
10     CGroup: /system.slice/gunicorn.service
11             ├─11682 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 -k uvicorn.workers.UvicornWorker --bind unix:/run/gunicorn.sock myproject.asgi:application
12             ├─11705 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 -k uvicorn.workers.UvicornWorker --bind unix:/run/gunicorn.sock myproject.asgi:application
13             ├─11707 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 -k uvicorn.workers.UvicornWorker --bind unix:/run/gunicorn.sock myproject.asgi:application
14             └─11708 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 -k uvicorn.workers.UvicornWorker --bind unix:/run/gunicorn.sock myproject.asgi:application
15
16Jun 10 21:03:29 django gunicorn[11705]: [2021-06-10 21:03:29 +0000] [11705] [INFO] ASGI 'lifespan' protocol appears unsupported.
17Jun 10 21:03:29 django gunicorn[11705]: [2021-06-10 21:03:29 +0000] [11705] [INFO] Application startup complete.
18Jun 10 21:03:30 django gunicorn[11707]: [2021-06-10 21:03:30 +0000] [11707] [INFO] Started server process [11707]
19Jun 10 21:03:30 django gunicorn[11707]: [2021-06-10 21:03:30 +0000] [11707] [INFO] Waiting for application startup.
20Jun 10 21:03:30 django gunicorn[11707]: [2021-06-10 21:03:30 +0000] [11707] [INFO] ASGI 'lifespan' protocol appears unsupported.
21Jun 10 21:03:30 django gunicorn[11707]: [2021-06-10 21:03:30 +0000] [11707] [INFO] Application startup complete.
22Jun 10 21:03:30 django gunicorn[11708]: [2021-06-10 21:03:30 +0000] [11708] [INFO] Started server process [11708]
23Jun 10 21:03:30 django gunicorn[11708]: [2021-06-10 21:03:30 +0000] [11708] [INFO] Waiting for application startup.
24Jun 10 21:03:30 django gunicorn[11708]: [2021-06-10 21:03:30 +0000] [11708] [INFO] ASGI 'lifespan' protocol appears unsupported.
25Jun 10 21:03:30 django gunicorn[11708]: [2021-06-10 21:03:30 +0000] [11708] [INFO] Application startup complete.

如果从弯曲的输出或systemctl 状态的输出表明出现问题,请检查日志以获取更多细节:

1sudo journalctl -u gunicorn

如果您对 /etc/systemd/systemd/system/gunicorn.service 文件进行更改,请重新加载 DAEMON 来重新读取服务定义,并通过键入重新启动 Gunicorn 过程:

1sudo systemctl daemon-reload
2sudo systemctl restart gunicorn

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

步骤 8 — 配置 Nginx 到 Proxy Pass 到 Gunicorn

现在Gunicorn已设置,您需要配置 Nginx 来传输流量到进程中. 在此步骤中,您将设置 Nginx 在Gunicorn 前面,以利用其高性能连接处理机制和易于实现的安全功能。

首先,在 Nginx 的可用站点目录中创建并打开一个新的服务器块:

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

在内部,打开一个新的服务器块,您将通过指定该块应该听正常端口80并应响应服务器的域名或IP地址开始:

1[label /etc/nginx/sites-available/myproject]
2server {
3    listen 80;
4    server_name server_domain_or_IP;
5}

接下来,告诉 Nginx 忽略找到 favicon 的任何问题,您还会告诉它在 `~/myprojectdir/static’ 目录中收集的静态资产在哪里找到。

 1[label /etc/nginx/sites-available/myproject]
 2server {
 3    listen 80;
 4    server_name server_domain_or_IP;
 5
 6    location = /favicon.ico { access_log off; log_not_found off; }
 7    location /static/ {
 8        root /home/sammy/myprojectdir;
 9    }
10}

最后,创建一个位置 / {}块来匹配所有其他请求. 在这个位置中,你将包含标准的proxy_params文件,包括在 Nginx 安装中,然后你将流量直接传输到 Gunicorn 接口:

 1[label /etc/nginx/sites-available/myproject]
 2server {
 3    listen 80;
 4    server_name server_domain_or_IP;
 5
 6    location = /favicon.ico { access_log off; log_not_found off; }
 7    location /static/ {
 8        root /home/sammy/myprojectdir;
 9    }
10
11    location / {
12        include proxy_params;
13        proxy_pass http://unix:/run/gunicorn.sock;
14    }
15}

完成后保存并关闭该文件. 现在,您可以通过链接到网站启用目录来启用该文件:

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

通过键入测试您的 Nginx 配置以检测语法错误:

1sudo nginx -t

如果没有报告错误,请继续通过键入重新启动 Nginx:

1sudo systemctl restart nginx

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

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

您现在应该能够访问您的服务器的域或 IP 地址,以查看 Django 欢迎页面,显示火箭图像。

<$>[注] 注: 配置 Nginx 后,下一步应该是通过 SSL/TLS 确保到服务器的流量,因为没有它,所有信息,包括密码,都通过网络以简单的文本发送。

如果你有一个域名,获得SSL证书以保护你的流量最简单的方法是使用Let's Encrypt(https://letsencrypt.org/)。

步骤 9 – 故障排除 Nginx 和 Gunicorn

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

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

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

Nginx 使用「server_name」来确定使用哪个服务器块来响应请求. 如果您收到默认的 Nginx 页面,这是一个迹象,表明 Nginx 无法明确匹配请求的 sever 区块,因此它会返回在 `/etc/nginx/sites-available/default 中定义的默认区块。

项目服务器块中的server_name必须比要选择的默认服务器块中的server_name更为具体。

Nginx 顯示 502 Bad Gateway 錯誤,而不是 Django 應用程式

502 错误表明 Nginx 无法成功代理请求. 各种配置问题以 502 错误表达,因此需要更多信息才能正确解决问题。

寻找更多信息的主要场所是在 Nginx 的错误日志中。 一般来说,这会告诉您在代理事件期间引起的问题的条件。

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

现在,请在浏览器中提出另一个请求,以生成新错误(尝试刷新页面)。

你可能會收到以下訊息:

1connect() to unix:/run/gunicorn.sock failed (2: No such file or directory)

這表明 Nginx 無法在該位置找到「gunicorn.sock」檔案,您應該將在「/etc/nginx/sites-available/myproject」檔案中定義的「proxy_pass」位置與「gunicorn.sock」檔案的實際位置進行比較,而該檔案是由「gunicorn.socket」 systemd 單位生成的。

如果您无法在/run目录中找到一个gunicorn.sock文件,这通常意味着 systemd 接口文件无法创建它. 返回检查 Gunicorn 接口文件部分(#checking-for-the-gunicorn-socket-file)以完成 Gunicorn 的故障排除步骤。

1connect() to unix:/run/gunicorn.sock failed (13: Permission denied)

这表明 Nginx 由于权限问题无法连接到 Gunicorn 接口,这可能发生在程序使用 root 用户而不是sudo用户时。

如果在根目录(/)和gunicorn.sock文件之间有有限的权限,则会发生这种情况,您可以通过将绝对路径传递到接口文件到namei命令来检查接口文件及其每个母目录的权限和所有权值:

1namei -l /run/gunicorn.sock
1[secondary_label Output]
2f: /run/gunicorn.sock
3drwxr-xr-x root root /
4drwxr-xr-x root root run
5srw-rw-rw- root root gunicorn.sock

输出显示了每个目录组件的权限. 通过查看权限(第一列),所有者(第二列)和组所有者(第三列),您可以确定允许对插件文件的访问类型。

在上面的示例中,接口文件和导致接口文件的每个目录都有世界读取和执行权限(目录的权限列以r-x而不是---结束)。

如果连接到连接器的任何目录都没有世界读取和执行权限,那么 Nginx 将无法访问连接器,而不允许世界读取和执行权限,或者确保组所有权被赋予 Nginx 是组的一部分。

Django表示:无法连接到服务器:连接被拒绝

在 Web 浏览器中尝试访问应用程序的部分时,您可能收到 Django 的一个信息是:

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

这表明 Django 无法连接到 Postgres 数据库,请通过键入确保 Postgres 实例正在运行:

1sudo systemctl status postgresql

如果不是,你可以启动它,并允许它在启动时自动启动(如果它尚未配置以这样做),键入:

1sudo systemctl start postgresql
2sudo 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 流程以通过键入获取更改:

1sudo systemctl restart gunicorn

如果您更改 Gunicorn 插槽或服务文件,请重新加载 DAEMON 并通过键入重新启动过程:

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

如果您更改了 Nginx 服务器块配置,请测试配置,然后通过键入 Nginx:

1sudo nginx -t && sudo systemctl restart nginx

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

结论

在本指南中,您已经在自己的虚拟环境中设置了 ASGI Django 项目,您已经配置了 Gunicorn 和 Uvicorn 以非同步地翻译客户端请求,以便 Django 能够处理它们。

Django通过提供许多常见元素来简化创建项目和应用程序的过程,使您能够专注于独特的元素。

Published At
Categories with 技术
comments powered by Disqus