手把手带你整得明明白白 Flask/Django+uWSGI+Nginx

Posted NightTeam

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手把手带你整得明明白白 Flask/Django+uWSGI+Nginx相关的知识,希望对你有一定的参考价值。

Web 项目(例如 Flask 项目、Django 项目)开发完成后定然是要部署到服务器上的,我也曾翻阅很多文章,零零碎碎地将知识点拼凑起来,还踩了不少的坑,最终实现了项目的部署。

这里将部署过程和配置说明作了整理,希望能够帮助到有需要的开发者。

本文围绕 Flask 和 Django 框架与 uWSGI 服务和 nginx 服务展开,将从服务器的安全组配置到 Python 的安装,从 uWSGI 的安装到启动,再讲解 Flask、Django 与 uWSGI 组合的配置,接着从 Nginx 的安装到 Flask/Django + uWSGI + Nginx 组合的配置,最后将讲解并演示前后端分离项目中前端项目的 Nginx 配置。

基础准备工作

基础准备工作中,我们将完成服务器安全组配置、Python 和 uWSGI 的安装,帮助新手趟过明明启动了却无法访问的坑。

服务器安全组配置

市面上大部分云服务器厂商的服务器都设有安全组,安全组是管理端口开闭的配置组。如果没有打开对应的安全组,那么就算再服务器启动了服务,用户在浏览器也无法访问服务的。

阿里云和华为云的服务器默认都有安全组,腾讯云默认不设安全组,京东云等其它厂商的服务器没接触过。

感谢信:谢谢群友 金鱼(林洁) 为本文实验提供的云服务器!

这里以阿里云服务器为例。

登录阿里云网站后点击右上角的控制台,在控制台中找到对应的服务器。

在服务器列表页的右上角点击更多选项,并从中找到网络和安全组选项,进而选择安全组配置选项。



在安全组列表页点击右侧的配置规则选项。


手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


在规则列表页点击左上角的添加安全组规则按钮,接着在弹出的面板中输入端口范围和授权对象。本文演示中用到的端口为 80、3000、3333 和 5000,所以这里设定的端口为 80 和 3000/5000


手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


授权对象默认填写 0.0.0.0/0,意思是对所有 IP 都开放。如果对安全性比较看重的朋友,可以填写指定 IP。配置完成后的安全组策略如下图所示:


手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


安装 Python 3

配置完安全组后,便可用 SSH 工具连接服务器。SSH 连接工具很多,直接用终端命令行也可以,我选择的是 Terminus。连接到服务器后的操作将用命令进行,首先我们需要查看当前 Python 版本:

$ python --version
Python 2.7.5

根据返回信息得知当前服务器中的 Python 版本为 2.7.5,如果我们的项目基于 Python 3+ 开发,那么就需要安装对应的版本,这里以 Python3.6 为例 。

在安装 Python 3.6 之前,需要先安装编译时用到的依赖:

$ yum -y groupinstall "Development tools"$ yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel$ yum install libffi-devel -y

一切妥当后下载对应版本的安装包,例如 Python3.6:

$ wget https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tar.xz

下载完成后解压:

$ tar -xvJf Python-3.6.0.tar.xz

创建编译安装的目录:

$ mkdir /usr/local/python3

进入刚才解压后得到的文件夹中,然后进行编译:

$ cd Python-3.6.0$ ./configure --prefix=/usr/local/python3$ make && make install

编译时间比较长,受服务器配置影响,整体时间约 3~8 分钟,请耐心等待。当终端出现 Successfully installed pip-9.0.1 setuptools-28.8.0 字样时代表编译完成。

为了方便我们在命令行执行 python 和 pip,这里需要为 Python3.6 创建软链接:

$ ln -s /usr/local/python3/bin/python3 /usr/local/bin/python3$ ln -s /usr/local/python3/bin/pip3 /usr/local/bin/pip3

命令执行后,当我们输入 python3 时指向的就是我们安装的 Python3.6。通过命令确认软链接创建情况:

$ python3 --version Python 3.6.0$ pip3 --version pip 9.0.1 from /usr/local/python3/lib/python3.6/site-packages (python 3.6)

安装并检查 uWSGI 服务

完成 Python3.6 的安装后便可以开始 uWSGI 的安装了。按照 uWSGI 官方文档 Installing uWSGI with Python support[1] 部分的指引,我们需要先安装 Python 支持:

$ yum install python-devel

然后便可以通过 pip 命令安装 uWSGI 了:

$ pip3 install uwsgi

命令执行后终端返回信息如下;

Successfully installed uwsgi-2.0.18

其中出现 Successfully 字样代表安装成功,从返回信息得知 uWSGI 的版本号为 2.0.18。要注意的是,当我们在终端运行:

$ uwsgi --version

时会得到如下提示:

-bash: uwsgi: command not found

这是因为系统找不到 uwsgi 命令。同样的,也要为 uWSGI 创建软链接:

ln -s /usr/local/python3/bin/uwsgi /usr/bin/uwsgi

此时再次运行 uwsgi --version 终端返回的就是正确的信息了:

2.0.18

完成 uWSGI 的安装工作后,我们可以通过一个示例来检测 uWSGI 是否能够正常工作。根据 uWSGI 官方文档 The first WSGI application[2] 部分的介绍,在系统任意目录(假设为 /root)中新建一个名为 foobar 的 Python 文件,并写入以下代码:

def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return [b"Hello World"]

这时候使用 uWSGI 提供的命令启动 foobar,并设定 HTTP 端口为 3000:

uwsgi --http :3000 --wsgi-file foobar.py

命令执行后,我们在浏览器中访问:

http://47.105.187.6:3000/

当浏览器中出现 Hello World 字样时代表 uWSGI 能够正常工作。

来自 www.sfhfpc.com[3] 算法和反爬虫站长韦世东的提示:可以使用 Ctrl + c 组合键关闭 uWSGI 服务。

Flask + uWSGI 组合拳

对于 Flask 项目的部署,uWSGI 官方文档也有给出相应的介绍,详见 Deploying Flask[4]

来自专业爬虫论坛 bbs.nightteam.cn 的提示:本文的 Flask 包括了 Flask 和 Flask restful。

在开始实验之前我们需要安装 Flask:

$ pip3 install Flask

然后新建一个名为 sailboat 的 Python 文件,并写入以下代码:

from flask import Flask
app = Flask(__name__)
@app.route('/')def index(): return "<span style='color:red'>Sailboat from GitHub</span>"

这段代码表示基于 Flask 创建了一个 Web 服务,设定的路由为 /,当用户访问根路由(即 /)时服务端将文字资源:

<span style='color:red'>Sailboat from GitHub</span>

返回给用户。当然,现在服务还没启动,用户也无法访问到指定的路由。使用 uWSGi 启动 Flask 项目时需要运行一长串命令:

uwsgi --http :3000 --wsgi-file sailboat.py --callable app --processes 4 --threads 2 --stats 127.0.0.1:9191

其中用到的 precesses、threads 和 stats 是可以省略掉的,因为它们只是附加的一些参数,并不会直接影响服务的启动。最后我们在浏览器中看到的是红色的文字:Sailboat from GitHub,即下图所示的界面:


手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


uWSGI 的配置文件

在你敲击完一长串命令并回车后,你会感觉很爽。然而这并没有什么卵用,过长的命令串极大地增加了你敲错命令的风险,它们是成正比的。uWSGI 团队也考虑到了这个问题,于是乎他们为 uWSGI 增加了配置文件的支持。例如命令串:

$ uwsgi --http-socket :9090 --psgi myapp.pl

用配置文件来表示可以写成:

[uwsgi]http-socket = :9090psgi = myapp.pl

假设这个 INI 配置文件的名称为 sailboat.ini,那么你启动它的命令为:

$ uwsgi -i sailboat.ini

这就舒服多了!除了 INI 之外,uWSGI 还支持 JSON[5]XML[6]  YAML[7] 等类型的配置文件。你可以根据个人习惯选择不同类型的配置文件,但大部分人使用的都是 INI。

上面启动 Flask 的命令串在 INI 中体现为:

[uwsgi]http = :3000wsgi-file = sailboat.pycallable = appprocesses = 4threads = 2stats = 127.0.0.1:9191

假设 INI 的文件名称为 sailboat,那么启动它的命令为:

$ uwsgi -i sailboat.ini

为项目指定虚拟环境

有的朋友可能会问,我的服务器上有多个项目,每个项目对应有 Python 虚拟环境,这种情况下我如何为项目指定对应的虚拟环境呢?

uWSGI 团队也考虑到了这个问题,我们只需要在 INI 中增加 virtualenv 配置项即可。假设要为 sailboat 指定路径为 “/usr/local/python3/lib/python3.6/site-packages/envsailboat” 的Python 虚拟环境,那么在 INI 中增加这项即可:

[uwsgi]+ virtualenv = /usr/local/python3/lib/python3.6/site-packages/envsailboathttp = :3000……

来自《Python3 反爬虫原理与绕过实战》作者韦世东的提示:其中的 “+” 号代表新增配置行,“……” 号代表省略其它配置。

以上就是使用 uWSGI 启动 Flask 的介绍,更多知识请翻阅 uWSGI 官方文档。

Django + uWSGI 组合拳

对于 Django 项目的部署,uWSGI 官方文档也有给出相应的介绍,详见 Deploying Django[8]

提示:本文的 Flask 包括了 Django 和 Django rest framework。

在开始实验之前我们需要安装 Django:

$ pip3 install django

与 uWSGI 一样,Django 安装完成后也不能直接在终端使用,否则会得到错误提示:

-bash: django-admin: command not found

同样的,我们为 django-admin 创建软链接。如果不知道 django-admin 目录具体路径,可以用 Linux 中的 find 命令进行查找:

$ find / -name "django-admin"/usr/local/python3/bin/django-admin

得到具体路径后再创建软链接:

$ ln -s /usr/local/python3/bin/django-admin /usr/bin/django-admin

接着就可以使用 django-admin 来创建一个 Django 项目了。例如创建一个名为 sfhfpc 的项目:

$ django-admin startproject sfhfpc

这时候我们就可以进入 sfhfpc 目录下启动它项目了:

$ cd sfhfpc$ python3 manage.py runserver 0.0.0.0:5000

这里要注意的是,如果安装的 Django 版本为 3.0,而操作系统是 CentOS 则会引发异常:

django.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17).

这是因为 Django 3.0 支持的 SQLite 最低版本为 3.8.3,而操作系统自带的 SQLite 版本为 3.7.17。解决这个异常的选择是升级 SQLite 版本或者降低 Django 版本。在实际应用中还需根据具体需求选择,这里我选择的是降低 Django 版本:

$ pip3 uninstall django$ pip3 install django==2.1.8

而后删除掉之前创建的 sfhfpc 项目,且在 Django 版本为 2.1.8 的基础上再次创建 sfhfpc 项目:

$ cd /root$ rm -rf /root/sfhfpc$ django-admin startproject sfhfpc

此时进入项目目录,通过 runserver 命令启动它:

$ cd sfhfpc$ python3 manage.py runserver 0.0.0.0:5000

在浏览器访问:

http://47.105.187.6:5000/

会得到如下显示:


手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


这是因为我们并没有按照 Django 的要求设置 HOSTS,同时说明 Django 能够正常相应用户的请求。此时进入 “/root/sfhfpc/sfhfpc” 中编辑名为 settings 的Python 文件,改动文件中关于 ALLOWED 的配置:

- ALLOWED_HOSTS = []+ ALLOWED_HOSTS = ["*"]

提示:“-” 号代表删除行,“+” 号代表新增行

而后回到 “/root/sfhfpc” 目录中,再次执行 runserver 命令便可正常启动 Django,此时页面显示内容如下:


手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


确保 Django 能够正常运行后,我们再学习如何用 uWSGI 启动 Django。

来自夜幕团队全员的温馨提示:记得用 Ctrl + c 组合键停止刚才启动的 Django 项目哦。

根据 uWSGI 官方文档  Deploying Django[9] 部分的指引,我们很快就能编写出对应的命令串:

uwsgi --http :5000 --chdir /root/sfhfpc/ --wsgi-file sfhfpc/wsgi.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191

对应的 INI 配置如下:

[uwsgi]http = :5000chdir = /root/sfhfpc/wsgi-file = sfhfpc/wsgi.pyprocesses = 4threads = 2stats = 127.0.0.1:9191

假设该 INI 配置文件名称为 sfhfpc.ini,那么它的路径为:

/root/sfhfpc/sfhfpc.ini

我们使用与 Flask 案例中通过 INI 启动 uWSGI 相同的命令:

$ uwsgi -i sfhfpc.ini

便可启动 Django 项目,命令执行后终端输出内容如下:

[uWSGI] getting INI configuration from sfhfpc.ini*** Starting uWSGI 2.0.18 (64bit) on [Sat Dec 14 12:41:59 2019] ***compiled with version: 4.8.5 20150623 (Red Hat 4.8.5-39) on 14 December 2019 03:25:29os: Linux-3.10.0-1062.1.2.el7.x86_64 #1 SMP Mon Sep 30 14:19:46 UTC 2019nodename: iZm5ehqonkrh3mzrarekw2Zmachine: x86_64clock source: unixpcre jit disableddetected number of CPU cores: 1current working directory: /root/sfhfpcdetected binary path: /usr/local/python3/bin/uwsgiuWSGI running as root, you can use --uid/--gid/--chroot options*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** chdir() to /root/sfhfpc/your processes number limit is 7271your memory page size is 4096 bytesdetected max file descriptor number: 65535lock engine: pthread robust mutexesthunder lock: disabled (you can enable it with --thunder-lock)uWSGI http bound on :5000 fd 4uwsgi socket 0 bound to TCP address 127.0.0.1:40032 (port auto-assigned) fd 3uWSGI running as root, you can use --uid/--gid/--chroot options*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** Python version: 3.6.0 (default, Dec 14 2019, 11:20:23) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]Python main interpreter initialized at 0xdef330uWSGI running as root, you can use --uid/--gid/--chroot options*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** python threads support enabledyour server socket listen backlog is limited to 100 connectionsyour mercy for graceful operations on workers is 60 secondsmapped 416880 bytes (407 KB) for 8 cores*** Operational MODE: preforking+threaded ***WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0xdef330 pid: 17724 (default app)uWSGI running as root, you can use --uid/--gid/--chroot options*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** spawned uWSGI master process (pid: 17724)spawned uWSGI worker 1 (pid: 17726, cores: 2)spawned uWSGI worker 2 (pid: 17727, cores: 2)spawned uWSGI worker 3 (pid: 17728, cores: 2)spawned uWSGI worker 4 (pid: 17729, cores: 2)*** Stats server enabled on 127.0.0.1:9191 fd: 18 ***spawned uWSGI http 1 (pid: 17730)

其中的 spawned uWSGI http 字样代表 uWSGI 成功启动。至于 WARNING: you are running uWSGI as root,实验中大可不必理会,但工作中必须遵守 uWSGI 的约定:不使用 root 用户运行 uWSGI。

提示:关于 Python 虚拟环境的设置请参考 uWSGI 文档,此处不再赘述。

此时浏览器中页面显示如下:

手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


浏览器呈现结果说明我们通过 uWSGI 启动了 Django 服务。

Nginx 的安装和启动

nginx 是一个高性能的 HTTP 和反向代理服务,也是一个 IMAP/POP3/SMTP 服务,其优点是内存 占用少、并发能力强、稳定性高。

nginx 是跨平台的,它可以在大多数类 UNIX 系统上运行,同时也 支持 Windows 系统。


手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


—— 引用自《Python3 反爬虫原理与绕过实战》

Nginx 的安装可参考 Nginx 官方文档的 Installing Nginx[10] 部分。这里以 CentOS 为例,演示 Nginx 的安装。按照文档指引,点击下图红色框中的链接:


手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


跳转到新页面后,根据自己的操作系统选择安装介绍,例如 CentOS:


手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


点击链接后会定位到对应的内容:


手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


总共有 4 步:安装工具、创建 repo、开启配置、安装 Nginx,照做便是。

首先安装 yum-utils:

$ sudo yum install yum-utils

然后创建 repo 文件:

$ vi /etc/yum.repos.d/nginx.repo

并将以下内容写入到 nginx.repo 中:

[nginx-stable]name=nginx stable repobaseurl=http://nginx.org/packages/centos/$releasever/$basearch/gpgcheck=1enabled=1gpgkey=https://nginx.org/keys/nginx_signing.keymodule_hotfixes=true
[nginx-mainline]name=nginx mainline repobaseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/gpgcheck=1enabled=0gpgkey=https://nginx.org/keys/nginx_signing.keymodule_hotfixes=true

接着开启配置:

$ sudo yum-config-manager --enable nginx-mainline

最后执行 Nginx 的安装命令:

$ sudo yum install nginx

命令执行后终端返回内容如下:

Running transaction checkRunning transaction testTransaction test succeededRunning transaction Installing : 1:nginx-1.17.6-1.el7.ngx.x86_64 1/1 ----------------------------------------------------------------------
Thanks for using nginx!
Please find the official documentation for nginx here:* http://nginx.org/en/docs/
Please subscribe to nginx-announce mailing list to getthe most important news about nginx:* http://nginx.org/en/support.html
Commercial subscriptions for nginx are available on:* http://nginx.com/products/
---------------------------------------------------------------------- Verifying : 1:nginx-1.17.6-1.el7.ngx.x86_64 1/1
Installed: nginx.x86_64 1:1.17.6-1.el7.ngx
Complete!

内容中出现 Thanks for using nginx 字样代表 Nginx 安装成功。

提示:安装过程中有可能出现类似 Is this ok [y/N] 的选项,输入 y 并回车即可。

Nginx 安装成功后并不会自行启动,启动它的命令如下:

$ systemctl start nginx

此时浏览器显示界面如下:

手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


Flask/Django + uWSGI + Nginx 组合拳

这真是几套神奇的组合, 为什么这么说呢?

首先,Flask 和 Django 自带服务,不需要 uWSGI 和 Nginx 也能启动。其次,uWSGI 可以与 Flask 和 Django 组合,不需要 Nginx 也能访问。最后,Flask/Django + uWSGI + Nginx 实际上是 Nginx 和 uWSGI 的关联,至于是 Flask 还是 Django ,Nginx 表示:我无所谓!

那为什么要使用 Nginx,直接用 Flask/Django 自带的服务不行吗?

说到底还是 Nginx 的处理能力太强了,Flask/Django 自带服务的能力太菜,uWSGI 给 Flask/Django 上了一层保险,但远不及 Nginx,所以就出现了 Flask/Django + uWSGI + Nginx 这种搭配。

Flask + Nginx 组合拳

Nginx 会根据配置文件呈现内容,它的配置文件目录为 “/etc/nginx/conf.d”,默认配置文件名为 default。default.conf 文件内容如下:

server { listen 80; server_name localhost;
#charset koi8-r; #access_log /var/log/nginx/host.access.log main;
location / { root /usr/share/nginx/html; index index.html index.htm; }
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; }
# proxy the php scripts to Apache listening on 127.0.0.1:80 # #location ~ .php$ { # proxy_pass http://127.0.0.1; #}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ .php$ { # root html; # fastcgi_pass 127.0.0.1:9000; # fastcgi_index index.php; # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; # include fastcgi_params; #}
# deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /.ht { # deny all; #}}

我们不必改动它的默认配置,为了方便管理,我们可以为每个项目都编写一份配置文件,例如 Flask 项目 porters 的配置文件命名为 porters.conf,同样存放在 “/etc/nginx/conf.d” 中。

来自 NightTeam 全员的提示:conf 文件的命令与具体的 Web 项目无关,可以随意命令。

首先,我们来看看 Flask 与 Nginx 的组合,假设 porters.py 包含如下代码:

from flask import Flask
app = Flask(__name__)
@app.route("/")def hello_world(): return f"<p>Hello!Porters.vip</p>"

if __name__ == "__main__": app.run(host="0.0.0.0", port=3333)

现在使用直接运行的方式启动这个 Flask 服务:

$ python3 porters.py

页面呈现内容如下:


手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


这代表 Flask 服务正常启动且外部可访问。新建名为 porters 的 Nginx 配置文件,并写入以下配置:

server { listen 3000; server_name 47.105.187.6; charset utf-8;
location / { proxy_pass http://localhost:3333; }}

配置的主要作用是让 Nginx 监听 3000 端口,并将请求转发到 http://localhost:3333。也就是说当用户在浏览器访问 http://localhost:3000 时,这个请求被转到服务器上端口号为 3333 的服务,也就是我们启动的 Flask 服务上。页面呈现内容如下:


手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


这正是刚才启动的 Flask 服务。此时访问 http://localhost:3333,得到同样的显示。

Flask + uWSGI + Nginx 组合拳

这里我们使用 INI 配置文件的方式启动 Flask 服务,porters 的 INI 配置如下:

[uwsgi]socket = 127.0.0.1:3333wsgi-file = porters.pycallable = appprocesses = 4threads = 2stats = 127.0.0.1:9191

保存后执行启动命令:

$ uwsgi -i porters.ini

这时候访问 http://47.105.187.6:3000 将得到错误提示:

手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


这是由于 Nginx 反向代理的类型为 HTTP 所致,如果代理的是 uWSGI 服务,需要新增对应配置。porters.conf 完整配置如下:

upstream uwsgis { server 127.0.0.1:3333;}
server { listen 3000; server_name 47.105.187.6; charset utf-8; location / { uwsgi_pass uwsgis; include uwsgi_params; }}

配置中引入了 uWSGi 的支持并配置了 uWSGI 对应的服务和端口。保存配置后执行 Nginx 配置重载命令:

$ nginx -s reload

此时页面呈现如下:


手把手带你整得明明白白 Flask/Django+uWSGI+Nginx


而访问 http://47.105.187.6:3333 时却显示无法访问。

以上就是 Flask + uWSGI + Nginx 的演示和介绍。

Django +uWSGI +Nginx 组合拳

上面演示的过程中,无论 Web 服务是 Flask 还是 Django 都不会影响 uWSGI 和 Nginx 的关系,所以只要按照 uWSGI 配置启动 Web 服务后,Django + uWSGI + Nginx 的配置方法与 Flask + uWSGI + Nginx 的配置方法是一样的。

前后端分离项目的 Nginx 配置

前后端分离是近年来较为常用的前端、后端分开开发的组合方式,这样能够有效提高双端开发效率。很多朋友不知道前端项目开发完毕、打包后得到的静态项目如何部署到服务器上。

首先,Vue、React 或 Angular 项目开发完毕后通常会用类似 yarn build  npm build 这样的命令将前端项目打包成静态文件——html、css、js 和图片等,假设你已经将项目打包好了,现在你计算机中的 build 目录下的文件就是你的 React 项目打包后得到的静态文件。

首先,你需要将项目上传到服务器中,例如 “/root/static”。如果你计算机的操作系统是类 Unix 系,那么可以用 scp 命令将项目上传到服务器,具体命令如下:

$ scp -r build root@47.105.187.6:/root/static

提示:命令执行后,上传前会要求你输入服务器登录密码,输入后回车即可。

待文件全部上传后,你便可以在 Nginx 的配置文件中配置静态文件的路径了。打开刚才使用的 porters.conf,在 server 级配置下新增部分配置:

location /build { alias /root/static/build; }

这部分配置的作用是将 “/root/static” 目录下的静态资源与路由 “/docs” 进行绑定,当用户在浏览器中访问 http://www.xxx.com/docs 时看到的是 “/root/static” 目录中的 index.html 页面。

我的计算机中并没有 Vue 或者 React 系的项目,一些静态文件:

api_data.js api_project.json img main.jsapi_data.json css index.html utilsapi_project.js fonts locales vendor

这些静态文件虽不是 React/Vue 项目打包而生成,但却与它们打包而生成的静态文件无异,此处不必多想,照做便是。

将 build 目录上传到 47.105.187.6 后按照上面的指引到 Nginx 配置文件中增加部分配置。保存后执行 Nginx 的配置重载命令:

$ nginx -s reload

用浏览器访问,此时页面呈现如下:



显示的是 403,这显然和配置没什么关系,是权限问题。打开 Nginx 的错误日志,看看究竟是什么原因:

$ cat /var/log/nginx/error.log

命令执行后终端便会显示 Nginx 错误日志中的内容,最下面的一句为:

"/root/static/build" failed (13: Permission denied), client: xx.xx.xx.xxx, server: 47.105.187.6, request: "GET /build HTTP/1.1", host: "47.105.187.6:3000"

其中的 Permission denied 说明 Nginx 没有权限读取 build 目录中的文件。再看看 Nginx 拥有的权限:

$ cat /etc/nginx/nginx.conf 
user nginx;worker_processes 1;
error_log /var/log/nginx/error.log warn;pid /var/run/nginx.pid;

events { worker_connections 1024;}

http { include /etc/nginx/mime.types; default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on; #tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;}

返回的配置中的第 1 行中表明此时 Nginx 的权限是 nginx,它是无法访问 root 用户下的文件的。这里我们将 user nginx 改为 user root 即可。

提示:实验并未考虑安全性等问题,具体工作中选择修改文件权限还是 Nginx user 请向公司运维或部门经理确认。

保存修改后执行 Nginx 配置重载命令:

$ nginx -s reload

再次访问 http://47.105.187.6:3000/build,此时页面呈现如下:



页面内容正确显示,说明部署成功。

以上就是前后端分离项目中前端 Nginx 配置的演示和介绍。

扩展知识:Django 静态文件的处理

有些时候,后端开发过程中会产生一些前端文件,例如 Django rest freamwok 开发时开启文档生成功能后便会产生部分静态文件,部署时就会产生静态文件无法正确显示的问题。

在 settings.py 文件中有个 STATIC_URL = '/static/',在它下面新增一行:

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

保存文件,然后在 Python 环境下执行命令:

$ python manage.py collectstatic

这样 Django 就会收集静态文件,放到指定目录内,也就是( Django 项目目录下的 static 内)。

除此之外,还需要在 Nginx 配置中设置静态文件路径:

location /static { alias /root/sfhfpc/sfhfpc/static; # 指向 Django 的 static 目录}

这样处理后,才能确保 Django rest framework docs 的样式能够正确显示。

参考文章

夜幕韦世东 -- 《不轻松,服务器部署nginx+uwsgi+djangorestfremework+react[11] 

忧臣解读 -- 《Centos7安装Python3.7[12]

版权声明

团队:NightTeam

链接:http://www.sfhfpc.com[13]

来源:算法和反爬虫

References

[1] Installing uWSGI with Python support: https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html#installing-uwsgi-with-python-support
[2] The first WSGI application: https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html#the-first-wsgi-application
[3] www.sfhfpc.com: http://www.sfhfpc.com
[4] Deploying Flask: https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html#deploying-flask
[5] JSON: https://uwsgi-docs.readthedocs.io/en/latest/Configuration.html#json-files
[6] XML: https://uwsgi-docs.readthedocs.io/en/latest/Configuration.html#xml-files
[7] YAML: https://uwsgi-docs.readthedocs.io/en/latest/Configuration.html#yaml-files
[8] Deploying Django: https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html#deploying-django
[9] Deploying Django: https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html#deploying-django
[10] Installing Nginx: http://nginx.org/en/docs/install.html
[11] 不轻松,服务器部署nginx+uwsgi+djangorestfremework+react: https://juejin.im/post/5b9b44eae51d450e7825f510#heading-23
[12] Centos7安装Python3.7: https://www.cnblogs.com/anxminise/p/9650206.html
[13] http://www.sfhfpc.com: http://www.sfhfpc.com/


以上是关于手把手带你整得明明白白 Flask/Django+uWSGI+Nginx的主要内容,如果未能解决你的问题,请参考以下文章

不了解布隆过滤器?一文给你整的明明白白!

原创不了解布隆过滤器?一文给你整的明明白白!

计算机网络如何学习 TCP 协议,这篇给你整的明明白白的!

学历长相家境普通的人,未来的发展方向是什么?00后的职业规划都已经整得明明白白

写好了功能/项目不知道怎么展示?手把手带你白嫖 Git Pages 部署自己的项目去惊艳面试官

HashMapConcurrentHashMapHashTable