Ubuntu16.04下uWSGI和Nginx部署Django项目

关于

本文是对How To Serve Django Applications with uWSGI and Nginx on Ubuntu 16.04(需翻墙访问)内容的翻译。
近日,为在Ubuntu16.04上部署Python Django项目,查询了非常多的资料,同时踩过无数坑,后通过Google找到此篇文章,基本顺利的实现了Django项目的部署。
不同于PHP或Java,Python项目的部署显得更加复杂一些,基于Apache或Tomcat的项目部署,常常只需要将项目文件夹放入对应WebApp文件夹即可。而在Python中,需要使用uWSGI软件,来实现HTTP与WSGI协议的适配,同时需要使用Ngnix服务器,启用反向代理来处理静态资源文件。同时,对于两者的管理,想要实现自动化,又需要编写对应的管理脚本。因此,如果开发者没有一定的Linux操作和Web部署的经验,那么这个过程会十分痛苦,踩坑无数。因此翻译此文,为使用Python做Web开发的工程师们提供一个更愉悦的工作体验。

部署环境版本说明

软件版本
Ubuntu16.04
uWSGI2.0.17.1
Nginx1.10.3

介绍

Django是一个功能强大的Web框架,可以帮助你开发Python应用程序或网站。 Django包含一个简化的开发服务器,用于在本地测试你的代码,但对于任何与生产相关的内容,都需要更安全,更强大的Web服务器。
在这篇教程中,我们将阐述如何在Ubuntu16.04的环境中下载和配置uWSGI应用容器,同时能够与我们开发的Web应用进行交互。然后,我们将设置Nginx反向代理到uWSGI服务,这将能使我们获得Nginx提供的安全与高性能的服务。

准备与目标

为了完成本教程,你需要一个全新的Ubuntu16.04的服务器,配置一个非root的用户,同时该用户能使用sudo操作获得root权限。
我们将在两个不同的虚拟环境中安装Django。 这将允许您的项目及其要求单独处理。 我们将创建两个示例项目,以便我们可以在多项目环境中执行这些步骤。
当我们准备好应用程序后,我们将安装和配置uWSGI应用程序服务器。该服务器将作为我们应用程序的接口,该接口可以使用HTTP协议将客户端的请求发送到我们应用程序的调用上边进行处理。然后,我们将在uWSGI前面设置Nginx,以利用其高性能连接处理机制及其易于实现的安全功能。
接下来,让我们开始本教程吧。

下载和配置VirtualEnv和VirtualEnvWrapper

我们将在各个虚拟环境中下载和配置我们的Django项目,以模拟隔离各种需求。为了这么做,我们需要下载virtualenv,该工具可以创建Python虚拟环境,同时下载virtualenvwrapper,该工具为virtualenv工作流程增加了一些可用性改进。
我们将使用Python包管理器pip安装这两个组件。 我们可以从Ubuntu存储库安装此实用程序。

  • Python2环境,则输入:
sudo apt-get update
sudo apt-get install python-pip
  • Python3环境,则输入:
sudo apt-get update
sudo apt-get install python3-pip

现在你已经安装了pip,我们可以在全局范围内安装virtualenvvirtualenvwrapper。 我们还将使用pip本身将pip升级到最新版本。

  • Python2环境,则输入:
sudo -H pip install --upgrade pip
sudo -H pip install virtualenv virtualenvwrapper
  • Python3环境,则输入:
sudo -H pip3 install --upgrade pip
sudo -H pip3 install virtualenv virtualenvwrapper

安装这些组件后,我们现在可以使用virtualenvwrapper脚本所需的信息配置shell。 我们的虚拟环境将全部放在名为Env的主文件夹中的目录中,以便于访问。 这是通过名为WORKON_HOME的环境变量配置的。 我们可以将它添加到我们的shell初始化脚本中,并可以获取虚拟环境包装器脚本。
如果你使用的Python3及pip3命令,你需要额外增加一条命令在你的初始化脚本中:

echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3" >> ~/.bashrc

不过你使用哪个Python脚本,你都需要执行以下命令:

echo "export WORKON_HOME=~/Env" >> ~/.bashrc
echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc

现在让你的配置立即生效:

source ~/.bashrc

你现在应该有Env目录出现在你的home目录中,同时其中包含了虚拟环境信息。

创建Django项目

现在我们有了虚拟环境工具,我们将创建两个虚拟环境,在每个环境中安装Django,并启动两个项目。

创建第一个项目

我们可以使用virtualenvwrapper脚本为我们提供的一些命令轻松创建虚拟环境。
通过以下命令,创建你的第一个虚拟环境:

mkvirtualenv firstsite

这将创建一个虚拟环境,在其中安装Python和pip,并激活环境。括号将提醒你现在正在新的虚拟环境中运行。它看起来像这样:(firstsite)user@hostname:〜$。 括号中的值是虚拟环境的名称。 通过pip安装的任何软件现在都将安装到虚拟环境中,而不是安装在全局系统上。 这允许我们在每个项目的基础上隔离我们的包。
我们的第一步是安装Django本身。 我们可以在没有sudo的情况下使用pip,因为我们在虚拟环境中本地安装它:

(firstsite) $ pip install django

Django下载完成后,我们可以开始创建第一个简单的项目:

(firstsite) $ cd ~
(firstsite) $ django-admin startproject firstsite

这将在你的home目录中创建一个名为firstsite的文件夹。 其中包括用于处理项目各个方面的管理脚本,以及用于存放实际项目代码的另一个同名目录。
进入到该项目中,同时进行最小程度的配置,以便本教程进行演示。

(firstsite) $ cd ~/firstsite

首先进行数据库migrate以初始化SQLite数据库(此次使用SQLite进行演示,也可以根据需求使用其他数据库,此处不作具体说明)。

(firstsite) $ ~/firstsite/manage.py migrate

您现在应该在项目目录中有一个名为db.sqlite3的数据库文件。 现在,我们可以通过输入以下内容来创建管理用户:

(firstsite) $ ~/firstsite/manage.py createsuperuser

此刻,你的项目目录(~/firstsite)应该有以下内容:

  • ~/firstsite/manage.py: Django项目的管理脚本
  • ~/firstsite/firstsite/: Django的项目目录. 其中包括 init.py, settings.py, urls.py, 和wsgi.py 文件.
  • ~/firstsite/db.sqlite3: SQLite数据库文件,包含本项目的数据库信息

接着,打开Django的配置文件:

(firstsite) $ vim ~/firstsite/firstsite/settings.py

首先找到ALLOWED_HOSTS指令。 这定义了可用于连接Django实例的服务器地址或域名列表。 不在此列表中的主机的任何传入请求都将引发异常。 Django要求你设置此参数以防止某类安全漏洞。
在方括号中,列出与Django服务器关联的IP地址或域名。 每个项目都应列在引号中,条目用逗号分隔。 如果你希望请求整个域和任何子域,请在条目的开头添加一个句点。 在下面的代码段中,有一些用于演示的注释掉的示例:

ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . .]

由于我们将设置Nginx来为我们的站点提供服务,因此我们需要配置一个目录来保存我们站点的静态资源文件。 这将允许Nginx直接为这些文件提供服务,这将对性能产生积极影响。 我们将告诉Django将它们放在项目基本目录中名为static的目录中。 将此行添加到文件的底部以配置此行为:

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

完成后保存并关闭文件。 现在,收集我们网站的静态元素,并输入以下内容将它们放在该目录中:

(firstsite) $ ~/firstsite/manage.py collectstatic

系统可能会要求您输入“是”以确认操作并收集静态内容。 项目目录中将有一个名为static的新目录。
接下来,我们可以打开一个端口,以便我们可以访问Django开发服务器。 如果您按照初始服务器设置指南进行操作,则应启用UFW防火墙。 键入以下内容允许连接到端口8080:

(firstsite) $ sudo ufw allow 8080

完成所有这些后,我们可以通过临时启动开发服务器来测试我们的项目。

(firstsite) $ ~/firstsite/manage.py runserver 0.0.0.0:8080

这将在端口8080上启动开发服务器。在浏览器中访问服务器的域名或IP地址,然后访问8080:

http://server_domain_or_IP:8080

成功的话将看到:

同样可以访问admin界面:
在这里插入图片描述
使用createsuperuser命令选择的管理登录凭据,登录到服务器。 将可以访问管理界面
在这里插入图片描述
同理,可以创建第二项目,此处进行省略,其方法同上。
详细代码和说明可参考原链接,由于篇幅过长,此处不再说明。

设置uWSGI应用服务器

uWSGI是一个应用程序服务器,可以通过名为WSGI的标准接口与应用程序进行通信。

下载uWSGI

与之前教程不同,在本节中,我们将全局安装uWSGI。 这将在处理多个Django项目时产生更少的冲突。 在我们安装uWSGI之前,我们需要安装软件所依赖的Python开发文件。 我们可以直接从Ubuntu的存储库安装它。

  • Python2环境,则输入:
sudo apt-get install python-dev
  • Python3环境,则输入:
sudo apt-get install python3-dev

现在开发环境准备好了,我们可以通过pip全局安装uWSGI。

sudo -H pip install uwsgi
  • Python3环境,则输入:
sudo -H pip3 install uwsgi

我们可以通过命令行将站点的基本信息传递给uWSGI服务进行测试。比如,我们可以通过以下命令进行测试:

uwsgi --http :8080 --home /home/sammy/Env/firstsite --chdir /home/sammy/firstsite -w firstsite.wsgi

在这里,我们通过--home告诉uWSGI使用〜/Env目录中的虚拟环境,通过--chdir切换到项目根目录,并使用存储在firstsite项目中的wsgi.py文件来提供相关服务(该文件自动生成)。 在我们的教程中,我们告诉它在端口8080上提供HTTP服务。
在浏览器访问你的站点,使用8080端口,你将再次看到你的站点(/admin界面中的静态元素如CSS将无法使用)。 完成此功能的测试后,在终端中键入CTRL-C退出。

创建配置文件

从命令行运行uWSGI对于测试很有用,但对实际部署不是特别有用。 相反,我们将以“Emperor模式”运行uWSGI,它允许主进程在给定一组配置文件的情况下自动管理单独的应用程序。
创建一个用于保存配置文件的目录。 由于这是一个全局过程,我们将创建一个名为/etc/uwsgi/sites的目录来存储我们的配置文件:

sudo mkdir -p /etc/uwsgi/sites

在此目录中,我们将放置配置文件。 我们需要为我们服务的每个项目配置一个配置文件。 uWSGI进程可以采用各种格式的配置文件,从简单性考虑,我们将使用.ini文件。
首先,为你的第一个项目创建配置文件:

sudo vi /etc/uwsgi/sites/firstsite.ini

在这个配置文件中,我们必须从[uwsgi]标签开始。 我们所有的信息都将在此标签下方。 我们还将使用变量的方式使我们的配置文件更具可重用性。 在[uwsgi]标签之后,使用你的第一个项目的名称设置一个名为project的变量。 添加一个名为uid的变量,用它保存你的sudo用户名。

[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)

接下来,我们需要配置uWSGI,以便它正确处理我们的项目。 我们需要通过设置chdir选项来切换到项目根目录。 我们可以使用相同的变量语法组合主目录和项目名称。
以类似的方式,我们将指出我们项目的虚拟环境。 通过设置模块,我们可以准确地指出如何与我们的项目进行交互(通过从我们内部项目目录中的wsgi.py文件中导入可调用的“application”)。 这些项的配置如下所示:

[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

我们想要创建一个包含5个worker的主进程。 我们可以通过添加以下内容来实现:

[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

master = true
processes = 5

接下来我们需要指定uWSGI应该如何监听连接。 在我们对uWSGI的测试中,我们使用了HTTP和网络端口。 但是,由于我们将使用Nginx作为反向代理,因此我们有更好的选择。
由于所有组件都在单个服务器上运行,因此我们可以使用Unix套接字,而不是使用网络端口。 这样更安全,性能更好。 这个套接字不会使用HTTP,而是实现uWSGI的uwsgi协议,这是一种快速二进制协议,用于与其他服务器通信。 Nginx可以使用uwsgi协议进行原生代理,因此这是我们的最佳选择。
我们还将修改套接字的所有权和权限,因为我们将为Web服务器提供写访问权限。 我们将设置vacuum选项,以便在服务停止时自动清除套接字文件:

[uwsgi]
project = firstsite
uid = sammy
base = /home/%(uid)

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

master = true
processes = 5

socket = /run/uwsgi/%(project).sock
chown-socket = %(uid):www-data
chmod-socket = 660
vacuum = true

有了这个,我们的第一个项目的uWSGI配置就完成了。 保存并关闭文件。
使用变量设置文件的优点是,它使重用变得异常简单。 复制第一个项目的配置文件,以用作第二个配置文件的基础:
有关第二个项目的操作,就由读者自行完成,有任何问题,可参考原链接或留言。

为uWSGI创建systemd单元文件

我们现在有了为Django项目提供服务所需的配置文件,但是我们仍然没有自动化该过程。 接下来,我们将创建一个systemd单元文件来管理uWSGI emperor进程并在启动时自动启动uWSGI。
我们将在/etc/systemd/system目录中创建单元文件,其中保留了管理员创建的单元文件。 我们将调用我们的文件uwsgi.service:

sudo vi /etc/systemd/system/uwsgi.service

从[Unit]部分开始,该部分用于指定元数据和订购信息。 我们在这里简单介绍一下我们的服务:

[Unit]
Description=uWSGI Emperor service

接下来,我们将配置[Service]部分。 我们将使用ExecStartPre指令来设置运行服务器所需的部分。 这将确保创建/run/uwsgi目录,并且我们的普通用户拥有它,并将www-data组作为组所有者。 即使不需要操作,带有-p标志的mkdirchown命令都会成功返回。 这就是我们想要的。
对于ExecStart指令指定的实际启动命令,我们将指向uwsgi可执行文件。 我们将告诉它以“Emperor模式”运行,允许它使用在/etc/uwsgi/sites中找到的文件管理多个应用程序。 我们还将添加systemd所需的部分以正确管理该过程。 这些来自uWSGI文档。

[Unit]
Description=uWSGI Emperor service

[Service]
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown sammy:www-data /run/uwsgi'
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

现在,我们需要做的就是添加[Install]部分。 这允许我们指定何时应该自动启动服务。 我们将服务绑定到多用户系统状态。 无论何时为多个用户设置系统(正常运行条件),我们的服务都将被激活:

[Unit]
Description=uWSGI Emperor service

[Service]
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown sammy:www-data /run/uwsgi'
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

[Install]
WantedBy=multi-user.target

我们目前无法成功启动服务,因为它依赖于www-data用户可用。 在安装Nginx之前,我们必须等待启动uWSGI服务。

下载和配置Nginx作为反向代理服务器

通过配置uWSGI并准备就绪,我们现在可以安装和配置Nginx作为我们的反向代理。 这可以从Ubuntu的默认存储库下载:

sudo apt-get install nginx

一旦安装了Nginx,我们就可以继续为每个项目创建一个服务器块配置文件。 通过创建服务器块配置文件从第一个项目开始:

sudo vi /etc/nginx/sites-available/firstsite

在配置文件中,我们可以通过指定端口号和域名来访问我们的项目。 server_name块必须与服务器的某个域名或其IP地址匹配,否则可能会使用默认的Nginx页面。 我们假设您拥有域名:

server {
    listen 80;
    server_name firstsite.com www.firstsite.com;
}

接下来,为Nginx指定图表及相关静态资源的地址:

server {
    listen 80;
    server_name firstsite.com www.firstsite.com;

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

接下来,我们可以创建一个catch-all位置块,将所有其他查询直接传递给我们的应用程序。 我们将包含/etc/nginx/uwsgi_params中的uwsgi参数,并将请求倒入到uWSGI服务器设置的套接字:

server {
    listen 80;
    server_name firstsite.com www.firstsite.com;
}

接下来,为Nginx指定图表及相关静态资源的地址:

server {
    listen 80;
    server_name firstsite.com www.firstsite.com;

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

    location / {
        include         uwsgi_params;
        uwsgi_pass      unix:/run/uwsgi/firstsite.sock;
    }
}

同理,进行第二个项目的相关配置
接下来,将新配置文件链接到Nginx的启用站点的目录以启用它们:

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

通过以下方式检查配置情况:

sudo nginx -t

如果未检测到语法错误,则可以重新启动Nginx服务以加载新配置:

sudo systemctl restart nginx

如果你还记得,我们从未真正启动过uWSGI服务器。 现在输入以下命令:

sudo systemctl start uwsgi

让我们将UFW规则删除到端口8080,而是允许访问我们的Nginx服务器:

sudo ufw delete allow 8080
sudo ufw allow 'Nginx Full'

你现在应该可以通过访问各自的域名来访问你的两个项目。 公共和管理界面都应该按预期工作。
如果顺利,你可以通过键入以下命令启用两个服务以在启动时自动启动:

sudo systemctl enable nginx
sudo systemctl enable uwsgi
注意:

配置Nginx后,下一步应该是使用SSL / TLS保护服务器的流量。 这很重要,因为没有它,所有信息(包括密码)都以纯文本形式通过网络发送。
如果你有域名,最简单的方法是获取SSL证书来保护您的流量,使用Let’s Encrypt。 按照此教程在Ubuntu 16.04上使用Nginx设置Let’s Encrypt。
如果您没有域名,您仍然可以使用自签名SSL证书保护您的站点以进行测试和学习。
(相关教程需翻墙浏览原作者链接)

常见错误及解决方案

如果你无法访问你的Web应用程序,则需要对安装进行故障排除。

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

如果Nginx显示默认页面而不是代理到你的应用程序,则通常意味着你需要调整/etc/nginx/sites-available/firstsite文件中的server_name以指向服务器的IP地址或域名。
Nginx使用server_name来确定用于响应请求的服务器目录。如果看到默认的Nginx页面,则表明Nginx无法正确地将请求与服务器目录相匹配,因此它会回退到/etc /nginx/sites-available/default中定义的默认块。
项目服务器中的server_name必须比要选择的默认服务器块中的server_name更具体。

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

502错误表示Nginx无法成功代理请求。各种配置问题都表现为502错误,因此需要更多信息才能正确排除故障。
查找更多信息的主要位置是Nginx的错误日志。通常,这将告诉你在代理事件期间导致问题的条件。 键入以下内容,查看Nginx错误日志:

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

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

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

这表明Nginx无法在给定位置找到套接字文件。 您应该将/etc/nginx/sites-available文件中的firstsite文件中定义的uwsgi_pass位置与/run/uwsgi目录中的firstsite.sock套接字文件的实际位置进行比较。
键入以下命令检查/run/uwsgi目录中是否存在套接字文件:

sudo ls /run/uwsgi

如果/run/uwsgi中没有套接字文件,通常意味着uwsgi进程无法创建它。检查uwsgi进程的状态以确定它是否能够启动:

sudo systemctl status uwsgi

如果systemctl status命令指示发生错误或者你未在目录中找到套接字文件,则表明uWSGI无法正确启动。 键入以下命令检查uWSGI进程日志:

sudo journalctl -u uwsgi

查看日志中的消息,找出uWSGI遇到问题的位置。 你可能遇到问题的原因有很多,但通常情况下,如果uWSGI无法创建套接字文件,则出于以下原因之一:

  • 项目文件由root用户而不是sudo用户拥有
  • /etc/systemd/system/uwsgi.service文件中的ExecStartPre行不包含用于创建目录和分配所有权的正确命令
  • /etc/nginx/sites-available目录中站点配置文件中的uwsgi_pass路径不是针对正确的套接字位置
  • /etc/uwsgi/sites目录中.ini文件中定义的uWSGI配置不正确。 检查以下项目:
    • chdir指令一旦插值,就指向主项目目录。
    • home指令一旦插值,就指向虚拟环境目录。
    • module指令使用Python模块导入语法从内部项目目录中加载wsgi.py文件。
    • socket指令指向/run/uwsgi文件中的文件(应该由上面提到的服务文件中的ExecStartPre行创建)。

如果对/etc/systemd/system/uwsgi.service文件进行了更改,请重新加载守护程序以重新读取服务定义并通过键入以下内容重新启动uWSGI进程:

sudo systemctl daemon-reload
sudo systemctl restart uwsgi

修复这些问题应该允许Nginx正确找到套接字文件。

connect() to unix:/run/uwsgi/firstsite.sock failed (13: Permission denied)

这表明由于权限问题,Nginx无法连接到uWSGI套接字。 通常,在受限制的环境中创建套接字或权限错误时会发生这种情况。 虽然uWSGI进程能够创建套接字文件,但Nginx无法访问它。
如果根目录(/)与套接字文件之间的任何点上的权限有限,则会发生这种情况。 我们可以通过将socket文件的绝对路径传递给namei命令来查看套接字文件及其每个父目录的权限和所有权值:

namei -nom /run/uwsgi/firstsite.sock
output:
f: /run/uwsgi/firstsite.sock
 drwxr-xr-x root  root     /
 drwxr-xr-x root  root     run
 drwxr-xr-x sammy www-data uwsgi
 srw-rw---- sammy www-data firstsite.sock

输出显示每个目录组件的权限。通过查看权限(第一列),所有者(第二列)和组所有者(第三列),我们可以确定允许哪种类型的访问套接字文件。
在上面的示例中,导致套接字文件的每个目录都具有全局读取和执行权限(目录的权限列以r-x而不是—结尾)。 www-data组对套接字本身具有组所有权。通过这些设置,Nginx进程应该能够成功访问套接字。
如果通向套接字的任何目录不属于www-data组,或者没有世界读取和执行权限,则Nginx将无法访问套接字。通常,这意味着配置文件有错误。
如果目录路径的权限或所有权过于严格,请查看/etc/systemd/system/uwsgi.service文件。ExecStartPre指令负责创建/run/uwsgi目录并将组所有权分配给www-data组。如果此处的命令不正确,则目录路径可能过于严格。
如果Nginx进程无法访问套接字文件本身,则/etc/uwsgi/sites.ini文件中定义的设置可能不正确。检查chown-socketchmod-socket的值,以确保Web进程具有访问文件的权限。

进一步排查

对于其他故障排除,日志可以帮助缩小根本原因。 依次检查每一个并查找指示问题区域的消息。
以下日志可能会有所帮助:
输入以下命令检查Nginx进程日志:sudo journalctl -u nginx
键入以下命令检查Nginx访问日志:sudo less /var/log/nginx/access.log
键入以下命令检查Nginx错误日志:sudo less /var/log/nginx/error.log
输入以下命令检查uWSGI应用程序日志:sudo journalctl -u uwsgi
在更新配置或应用程序时,可能需要重新启动进程以根据更改进行调整。
如果更新Django应用程序,可以通过键入以下命令重新启动uWSGI进程以获取更改:

sudo systemctl restart uwsgi

如果更改uwsgi systemd服务文件,请重新加载守护程序并键入以下命令重新启动该过程:

sudo systemctl daemon-reload
sudo systemctl restart uwsgi

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

sudo nginx -t && sudo systemctl restart nginx

后记

相信通过此教程,多数的读者都能正确的配置好基于uWSGI和Nginx的Django项目,如果还有什么问题,可以留言大家一同交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值