简介
Django是一个强壮的网络框架,能够协助你的Python应用程序或网站起步。Django包含一个简化的开发服务器,用于在本地测验你的代码,但关于任何与生产有关的作业,都需求一个更安全和强壮的Web服务器。
布置Django应用程序的传统方式是运用Web服务器网关接口(WSGI)。然而,随着Python 3的呈现和对异步履行的支撑,你现在能够经过异步服务器网关接口(ASGI)的异步可调用程序履行你的Python应用程序。作为WSGI的继承者,Python中的ASGI规范是WSGI的超集,能够作为WSGI的替代品。
Django答应 “外部异步,内部同步 “模式,答应你的代码在内部同步,而ASGI服务器异步处理恳求。经过答应webserver有一个异步的可调用性,它能够为每个应用程序处理多个传入和传出的事情。Django应用程序内部依然是同步的,以答应向后兼容,并避免并行计算的复杂性。这也意味着你的Django应用不需求改动就能够从WSGI切换到ASGI。
在本攻略中,你将在Ubuntu 20.04上装置和装备一些组件以支撑和服务Django应用程序。你将设置一个PostgreSQL数据库,而不是运用默许的SQLite数据库。你将装备Gunicorn应用服务器与Uvicorn,一个ASGI实现,以异步地与你的应用程序衔接。然后,你将设置Nginx作为Gunicorn的反向署理,使你能够运用它的安全和性能特性来服务你的应用程序。
前提条件
要完结本教程,你将需求。
- 一台依照Ubuntu 20.04初始服务器设置攻略设置的Ubuntu 20.04服务器,包含一个具有
sudo
权限的非root用户。
第1步 – 从Ubuntu软件库中装置软件包
为了开端这个过程,你将从Ubuntu软件库中下载并装置你需求的一切项目。稍后你将运用 Python 软件包办理器pip
来装置其他组件。
首要,你需求更新本地apt
包索引,然后下载并装置软件包。你所装置的软件包取决于你的项目将运用哪个版别的 Python。
运用下面的指令来装置必要的系统包。
sudo apt update
sudo apt install python3-venv libpq-dev postgresql postgresql-contrib nginx curl
这个指令将装置用于树立虚拟环境的Python库、Postgres数据库系统和与之交互所需的库,以及Nginx网络服务器。接下来,你将为你的Django应用程序创立PostgreSQL数据库和用户。
第2步 – 创立PostgreSQL数据库和用户
在这一步,你将为你的Django应用程序创立一个数据库和数据库用户。
默许状况下,Postgres对本地衔接运用一种叫做 “同行认证 “的认证方案。这意味着,假如用户的操作系统用户名与有效的Postgres用户名相匹配,该用户就能够登录,而无需进一步的认证。
在Postgres装置过程中,创立了一个名为postgres
的操作系统用户,与postgres
PostgreSQL办理用户对应。你将需求运用这个用户来履行办理使命。你能够运用sudo并经过-u
选项来输入用户名。
经过键入登录到一个交互式Postgres会话。
sudo -u postgres psql
你将得到一个PostgreSQL的提示,你能够在这儿设置要求。
首要,为你的项目创立一个数据库。
CREATE DATABASE myproject;
**留意:**每个Postgres语句有必要以分号结束。假如你遇到问题,确保你的指令以分号结束。
接下来,为该项目创立一个数据库用户。确保挑选一个安全的暗码。
CREATE USER myprojectuser WITH PASSWORD 'password';
之后,你要为你刚创立的用户修正一些衔接参数。这将加速数据库的操作,这样就不用在每次树立衔接时都要查询和设置正确的值。
你将把默许编码设置为UTF-8
,这是Django所希望的。你还会将默许的业务阻隔方案设置为 “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能够衔接并办理它的数据库信息。
第3步 – 为你的项目创立一个Python虚拟环境
现在你现已有了一个数据库,你能够开端预备你项目的其他需求。你将在一个虚拟环境中装置你的Python需求,以方便办理。
首要,创立并移入一个能够保存项目文件的目录。
mkdir ~/myprojectdir
cd ~/myprojectdir
然后运用 Python 内置的虚拟环境东西来创立一个新的虚拟环境。
python3 -m venv myprojectenv
这将创立一个名为 myprojectenv
在你的 myprojectdir
目录中。 在里边,它将装置一个本地版别的 Python 和一个本地版别的pip
。 你能够用它来为你的项目装置和装备一个孤立的 Python 环境。
在装置项目的 Python 需求之前,你需求激活这个虚拟环境。你能够经过输入以下内容来完结。
source myprojectenv/bin/activate
你的提示应该改动,以标明你现在是在一个 Python 虚拟环境中操作。 它看起来会像这样。 (myprojectenv)user@host:~/myprojectdir$
.
你将在虚拟环境中装置Django。将Django装置到一个特定于你的项目的环境中,将答应你的项目和它们的需求被分开处理。在你的虚拟环境激活后,用pip
的本地实例装置Django、Gunicorn、Uvicorn和psycopg2
PostgreSQL适配器。
**留意:**当虚拟环境被激活时 (当你的提示符前面有(myprojectenv)
) ,运用pip
而不是pip3
,即使你运用的是 Python 3。虚拟环境中的东西副本总是被命名为pip
,不论 Python 的版别怎么。
pip install django gunicorn uvicorn psycopg2-binary
现在你应该具有发动Django项目所需的一切软件。
第四步 – 创立和装备一个新的 Django 项目
在装置了Python组件后,你能够创立实践的Django项目文件。
创立Django项目
由于你现已有了一个项目目录,你能够告知Django将文件装置在这儿。它将创立一个包含实践代码的二级目录,这很正常,并在这个目录中放置一个办理脚本。这其中的关键是你清晰界说了这个目录,而不是让Django相关于你的当时目录做出决议。
django-admin startproject myproject ~/myprojectdir
在这一点上,你的项目目录 (~/myprojectdir
在本教程中)应该有以下内容。
-
~/myprojectdir/manage.py
: 一个Django项目办理脚本。 -
~/myprojectdir/myproject/
: Django项目包。 这应该包含__init__.py
,asgi.py,
settings.py
,urls.py
, 和wsgi.py
文件。 -
~/myprojectdir/myprojectenv/
: 你之前创立的虚拟环境目录。
调整项目设置
创立完项目文件后,你需求调整一些设置。在你的文本编辑器中翻开设置文件。
nano ~/myprojectdir/myproject/settings.py
首要找到ALLOWED_HOSTS
指令。这界说了一个服务器地址或域名的列表,可用于衔接到Django实例。任何带有不在此列表中的Host头的传入恳求都会引发一个异常。Django要求你设置这个,以避免某类安全漏洞的产生。
在方括号内,列出与你的Django服务器相关的IP地址或域名。在引号中列出每一项,条目之间用逗号离隔。要答应整个域名和任何子域名,请在条目的最初加上一个句号。在下面的片段中,有几个被注释过的比如,用来演示怎么做到这一点。
**留意:**请确保将localhost
作为选项之一,由于你将经过本地Nginx实例来署理衔接。
~/myprojectdir/myproject/settings.py
. . .
# 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
设置成一个空字符串。
~/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/'
import os
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
在你的网络浏览器中,拜访你的服务器的域名或IP地址,然后输入:8000
。
http://server_domain_or_IP:8000
你应该收到默许的Django索引页。
假如你在地址栏中的URL末尾加上/admin
,你会被提示输入你用createsuperuser
指令创立的办理用户名和暗码。
在认证之后,你能够拜访默许的Django办理界面。
当你完结探究后,在终端窗口点击CTRL+C
,封闭开发服务器。
测验Gunicorn对项目的服务才能
在本教程中,你将运用Gunicorn与Uvicorn搭配来布置应用程序。尽管Gunicorn传统上是用来布置WSGI应用程序的,但它也供给了一个可插拔的接口来供给ASGI布置。它经过答应你消费由ASGI服务器(uvicorn
)暴露的作业者类来做到这一点。由于Gunicorn是一个更老练的产品,比Uvicorn供给更多的装备,Uvicorn的维护者主张运用gunicorn
,并运用uvicorn
工人类作为全功用的服务器和进程办理器。
在脱离虚拟环境之前,你要测验Gunicorn以确保它能为应用程序供给服务。
要运用uvicorn
作业者和gunicorn
服务器,进入你的项目目录,运用下面的gunicorn
指令来加载项目的ASGI模块。
cd ~/myprojectdir
gunicorn --bind 0.0.0.0:8000 myproject.asgi -w 4 -k uvicorn.workers.UvicornWorker
这将在Django开发服务器所运转的同一界面上发动Gunicorn。你能够回去再次测验该应用程序。
**留意:**不需求运用Gunicorn来运转你的ASGI应用程序。假如只运用uvicorn
,你能够运用以下指令。
uvicorn 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应用程序的装备。你能够经过键入来退出虚拟环境。
deactivate
你的提示符中的虚拟环境指示灯将被移除。
第五步 – 为 Gunicorn 创立 systemd Socket 和服务文件
在上一节中,你测验了Gunicorn能够与Django应用程序交互。在这一步,你将经过创立 systemd 服务和套接字文件来实现一种更强壮的发动和停止应用服务器的方式。
Gunicorn 套接字将在发动时被创立,并将监听衔接。当有衔接产生时,systemd 会主动发动 Gunicorn 进程来处理衔接。
首要,以sudo
的权限为 Gunicorn 创立并翻开一个 systemd 套接字文件。
sudo nano /etc/systemd/system/gunicorn.socket
在文件中,你将创立一个[Unit]
部分来描述套接字,一个[Socket]
部分来界说套接字的方位,还有一个[Install]
部分来确保套接字在正确的时间被创立。
/etc/systemd/system/gunicorn.socket
[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
指令来标明这种联系。
/etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
接下来,翻开[Service]
部分。你将指定该进程的用户和组。你将把进程的一切权交给你的一般用户账户,由于它具有一切相关文件。你将把组的一切权交给www-data
组,这样Nginx就能够很容易地与Gunicorn通讯。
然后,你将制作作业目录,并指定发动该服务的指令。在这种状况下,你有必要指定Gunicorn可履行文件的完整途径,该文件已装置在虚拟环境中。你将把进程绑定到你在/run
目录中创立的Unix套接字上,以便进程能够与Nginx通讯。你将把一切数据记录到规范输出,以便journald
进程能够收集Gunicorn日志。你还能够在这儿指定任何可选的Gunicorn调整。下面是一个指定三个作业进程的比如。
/etc/systemd/system/gunicorn.service
[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 - \
-k uvicorn.workers.UvicornWorker \
--workers 3 \
--bind unix:/run/gunicorn.sock \
myproject.asgi:application
最终,你要增加一个[Install]
部分。这将告知systemd,假如你让这个服务在开机时发动,应该把它链接到什么地方。你会希望这个服务在一般多用户系统发动时发动。
/etc/systemd/system/gunicorn.service
[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 - \
-k uvicorn.workers.UvicornWorker \
--workers 3 \
--bind unix:/run/gunicorn.sock \
myproject.asgi:application
[Install]
WantedBy=multi-user.target
至此,systemd 服务文件完结。现在保存并封闭它。
现在你能够发动并启用Gunicorn套接字。这将在/run/gunicorn.sock
,并在发动时创立套接字文件。 当有衔接进入该套接字时,systemd 会主动发动gunicorn.service
来处理。
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
现在你现已树立了 systemd 服务和套接字文件,你将经过查看套接字文件来承认操作是否成功。
第6步 – 查看Gunicorn套接字文件的存在
在这一步,你将查看Gunicorn套接字文件的状况。首要,查看进程的状态,了解它是否能够发动。
sudo systemctl status gunicorn.socket
输出结果将与此相似。
Output● gunicorn.socket - gunicorn socket
Loaded: loaded (/etc/systemd/system/gunicorn.socket; enabled; vendor prese>
Active: active (listening) since Fri 2020-06-26 17:53:10 UTC; 14s ago
Triggers: ● gunicorn.service
Listen: /run/gunicorn.sock (Stream)
Tasks: 0 (limit: 1137)
Memory: 0B
CGroup: /system.slice/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
文件,在持续之前处理任何问题。
第7步 – 测验插座的激活
在这一步,你将测验套接字的激活状况。现在,假如你只发动了gunicorn.socket
单元,gunicorn.service
还没有被激活,由于套接字还没有收到任何衔接。你能够经过键入来查看这一点。
sudo systemctl status gunicorn
Output● 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
Output
● gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
Active: active (running) since Thu 2021-06-10 21:03:29 UTC; 13s ago
TriggeredBy: ● gunicorn.socket
Main PID: 11682 (gunicorn)
Tasks: 4 (limit: 4682)
Memory: 98.5M
CGroup: /system.slice/gunicorn.service
├─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
├─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
├─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
└─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
Jun 10 21:03:29 django gunicorn[11705]: [2021-06-10 21:03:29 +0000] [11705] [INFO] ASGI 'lifespan' protocol appears unsupported.
Jun 10 21:03:29 django gunicorn[11705]: [2021-06-10 21:03:29 +0000] [11705] [INFO] Application startup complete.
Jun 10 21:03:30 django gunicorn[11707]: [2021-06-10 21:03:30 +0000] [11707] [INFO] Started server process [11707]
Jun 10 21:03:30 django gunicorn[11707]: [2021-06-10 21:03:30 +0000] [11707] [INFO] Waiting for application startup.
Jun 10 21:03:30 django gunicorn[11707]: [2021-06-10 21:03:30 +0000] [11707] [INFO] ASGI 'lifespan' protocol appears unsupported.
Jun 10 21:03:30 django gunicorn[11707]: [2021-06-10 21:03:30 +0000] [11707] [INFO] Application startup complete.
Jun 10 21:03:30 django gunicorn[11708]: [2021-06-10 21:03:30 +0000] [11708] [INFO] Started server process [11708]
Jun 10 21:03:30 django gunicorn[11708]: [2021-06-10 21:03:30 +0000] [11708] [INFO] Waiting for application startup.
Jun 10 21:03:30 django gunicorn[11708]: [2021-06-10 21:03:30 +0000] [11708] [INFO] ASGI 'lifespan' protocol appears unsupported.
Jun 10 21:03:30 django gunicorn[11708]: [2021-06-10 21:03:30 +0000] [11708] [INFO] Application startup complete.
假如来自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
在持续之前,请确保你扫除了上述问题的毛病。
第8步 – 装备Nginx以署理传递给Gunicorn
现在Gunicorn现已设置好了,你需求装备Nginx将流量传递给该进程。在这一步,你将在Gunicorn前面设置Nginx,以使用其高性能的衔接处理机制和易于实现的安全功用。
首要,在Nginx的sites-available
目录中创立并翻开一个新的服务器块。
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”,所以你能够创立一个方位块来匹配这些恳求。
/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/sammy/myprojectdir;
}
}
最终,创立一个location / {}
块,以匹配一切其他恳求。在这个方位,你将包含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/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地址,查看显现有火箭图片的Django欢迎页面。
**留意:**在装备完Nginx后,下一步应该是运用SSL/TLS来确保服务器的流量安全。这一点很重要,由于假如没有它,一切的信息,包含暗码,都是以纯文本方式经过网络发送的。
假如你有一个域名,最简略的方法是运用Let’s Encrypt来取得SSL证书,以确保你的流量。依照本攻略,在Ubuntu 20.04上用Nginx设置Let’s Encrypt。运用本教程中创立的Nginx服务器块,依照该过程操作。
第9步 – 扫除Nginx和Gunicorn的毛病
假如最终一步没有显现你的应用程序,你将需求对你的装置进行毛病扫除。
Nginx显现的是默许页面而不是Django应用程序
假如Nginx显现默许页面,而不是署理到你的应用程序,这一般意味着你需求调整server_name
内的 /etc/nginx/sites-available/myproject
文件,以指向你的服务器的IP地址或域名。
Nginx运用server_name
来决议运用哪个服务器块来呼应恳求。假如你收到的是Nginx的默许页面,这标明Nginx无法将恳求清晰匹配到一个服务器块,所以它回到了/etc/nginx/sites-available/default
中界说的默许块。
你项目中的服务器块server_name
,有必要比默许服务器块中的更具体,才能被选中。
Nginx显现502坏网关过错,而不是Django应用程序
502过错标明Nginx无法成功署理恳求。许多装备问题都会呈现502过错,因而需求更多的信息来正确扫除毛病。
寻觅更多信息的首要地方是Nginx的过错日志。一般来说,这将告知你在署理事情中哪些条件导致了问题。依照Nginx的过错日志,输入。
sudo tail -F /var/log/nginx/error.log
现在,在浏览器中做另一个恳求,产生一个新的过错(测验改写页面)。你应该收到一条新的过错信息写到日志中。假如你看一下该信息,应该能够协助你缩小问题的规模。
你或许会收到以下信息。
“`[secondary_label Output]
connect() to unix:/run/gunicorn.sock failed (2: No such file or directory)
OutputThis indicates that Nginx could not find the `gunicorn.sock` file at the given location. You should compare the `proxy_pass` location defined within `/etc/nginx/sites-available/myproject` file to the actual location of the `gunicorn.sock` file generated by the `gunicorn.socket` systemd unit.
If you cannot find a `gunicorn.sock` file within the `/run` directory, it generally means that the systemd socket file was unable to create it. Go back to the [section on checking for the Gunicorn socket file](#checking-for-the-gunicorn-socket-file) to step through the troubleshooting steps for Gunicorn.
```
connect() to unix:/run/gunicorn.sock failed (13: Permission denied)
这标明Nginx由于权限问题而无法衔接到Gunicorn套接字。当程序运用根用户而不是sudo
用户时,或许会产生这种状况。 尽管systemd能够创立Gunicorn套接字文件,但Nginx却无法拜访它。
假如在根目录(/
)和gunicorn.sock
文件之间的任何一点上存在有限的权限,就会产生这种状况。你能够经过将套接字文件的绝对途径传递给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
输出显现每个目录组件的权限。经过查看权限(榜首列)、一切者(第二列)和组一切者(第三列),你能够弄清楚答应对socket文件的什么类型的拜访。
在上面的比如中,套接字文件和通往套接字文件的每个目录都有世界读和履行的权限(目录的权限栏以r-x
结束,而不是---
)。 Nginx进程应该能够成功拜访该套接字。
假如通往套接字的任何目录没有世界读取和履行的权限,Nginx将无法拜访套接字,除非答应世界读取和履行的权限,或许确保组的一切权被赋予Nginx所属的组。
Django显现:”could not connect to server:衔接被回绝”
当你试图在网络浏览器中拜访应用程序的某些部分时,你或许会从Django收到一条信息。
“`[secondary_label Output]
OperationalError at /admin/login/
could not connect to server:衔接被回绝
服务器是否在主机 “localhost”(127.0.0.1)上运转,并
在5432端口承受TCP/IP衔接?
This indicates that Django is unable to connect to the Postgres database. Make sure that the Postgres instance is running by typing:
```command
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
这些指令有助于在你调整装备的过程中捕捉到改变。
总结
在本攻略中,你现已在自己的虚拟环境中设置了一个ASGI Django项目。你装备了Gunicorn和Uvicorn来异步翻译客户端恳求,以便Django能够处理它们。之后,你设置了Nginx作为一个反向署理来处理客户端衔接,并根据客户端恳求供给正确的项目。
Django简化了创立项目和应用程序的过程,供给了许多常见的部分,使你能够专注于共同的元素。经过使用本文描述的一般东西链,你能够从一个服务器上为你创立的应用程序供给服务。