nginx的作用:
一、静态文件服务器和反向代理django服务
django框架中的静态文件服务只在开发调试时提供服务,当以生产模式运行时需要将静态文件部署到静态文件服务器上。
1. 收集django项目中的静态文件
在配置文件中配置STATIC_ROOT
我们在我的项目中里base_setting的配置文件中添加一下。
STATIC_ROOT = BASE_DIR / 'static'
然后运行命令 python manage.py collectstatic,会将项目中所需要的静态文件收集到STATIC_ROOT目录下。
大家看我后端项目中是不是多了一个static这个文件夹~
u 运行完之后,我们就把 STATIC_ROOT = BASE_DIR / 'static' 这行代码删掉,然后git add . 等提交代码到gitee远程仓库上面去。然后在云服务器上面的当前项目里再git pll拉取下来,这个时候我们云服务器上面的当前项目里就有static这个文件夹啦。
在服务器上创建nginx 文件夹,将static目录拷贝到其中。
cp -r ./django_app/static ./nginx/
2. 配置静态文件服务器
docker pull nginx:alpine
启动nginx容器
docker run -it --name ck13_nginx --network ck13 nginx:alpine /bin/sh
查看配置文件存放路径:
把nginx的配置文件拷贝到当前目录下:
docker cp ck13_nginx:/etc/nginx/nginx.conf ./
我们查看一下配置文件的结构:
我们看到最下面一行include /etc/nginx/conf.d/*.conf ,所以我们再把此目录下的conf文件复制过来看下是啥意思。
docker cp ck13_nginx:/etc/nginx/conf.d/ ./
一个server{} 代表一个服务
listen: 80 # 监听端口
server_name:localhost # 可以写你的主机也可以写你的域名。一个端口配几个域名就需要几个server{}
location / : 定位的指令。 /代表根
root /usr/share/nginx/html # root是指文件的根目录
修改端口为9400:
vi default.conf
修改完之后需要重新加载配置:
nginx -s reload
试了一下 好像不行,那我们只能关掉nginx,再重新启动
排查问题发下我们上面还没映射端口,删掉容器 重新创建一个:(记得云服务器安全组去开放9400端口)
docker run -it --name ck13_nginx -p 9400:80 --network ck13 nginx:alpine /bin/sh
我们查看上述说的 conf文件中 location 里 root /usr/share/nginx/html # root是指文件的根目录
此时我们访问 www.hhxpython.com 返回/usr/share/nginx/html/index.html文件
我们在当前目录下创建一个aaa.txt
那此时 如果我们访问的路径是:
www.hhxpython.com/aaa.txt 返回/usr/share/nginx/html/aaa.txt
这个时候我们去访问,就出来了。
其实这就是我们说的静态文件服务
那如果我们把配置文件改成这样子
修改云服务器上面刚才把nginx配置文件目录复制到云服务器里面的项目里面的nginx目录下配置文件
我们把原来创建的nginx干掉,重新创建一个。
docker ps | grep nginx
docker stop ck13_nginx
docker rm ck13_nginx
在重新生成容器之前,我们希望把上面我们刚刚创建的static目录和conf.d目录拷贝过去。
我们重新启动一个nginx容器
docker run -d --name ck13_nginx -p 9400:80 -v /ck13/manual/nginx/conf.d:/etc/nginx/conf.d -v /ck13/manual/nginx/static:/usr/share/nginx/html/static --network ck13 nginx:alpine
进入这个容器发现default.conf已经映射过来了。
接下来我们再看static有没有映射进来, cd到/usr/share/nginx/html/。
是不是映射进来啦。
好,那我们现在想在浏览器上随便访问下面这一张图片,我该怎么办呢?
我们现在直接访问,为什么访问不了?因为我们现在还没有配。
那现在我们想找到怎么办呢?输入以下网址:
http://123.60.113.190:9400/static/admin/img/icon-addlink.svg
加号+ 是不是出来啦。
怎么实现的呢?我们来讲解一下:
所以最后找的文件就是/usr/share/nginx/html/static/admin/img/icon-addlink.svg
有些人会问,那你怎么知道admin/img/icon-addlink.svg? 因为你后端django项目这个图片存放路径就是这个哇。
有些人还会问,那为啥location里面不用root呢?为什么改成alias?
因为你用root的话是指文件的根目录,不管匹配路径,都是把域名后面的路径和根目录拼接到一起。 但是你有/static/这个前缀哇。当然了你要用root写的话也可以改成这样子。
你可以这么访问:
地址: 域名:端口/static/admin/img/icon-addlink.svg
但是这样子的话,有一个不好的地方,是不是别人都能知道你的路径啦?
3. 配置django后端服务
那这个后端服务是怎么配的呢?其实跟上面静态服务配置是一样的。
以前我们启动django后台服务是不是这么操作的?点击绿色三角形图标 ,那我们点击一下看看效果,然后打开这个地址 。
我们看到这些都是静态文件,访问接口也是直接返回一个html页面,这个是前后端不分离。
可以看到静态文件和接口访问的域名都是在同一个域名上面。
所以我们现在配置的时候,需要配置到同一个server{}里面。
所以我们上面在server{}里面配置了静态文件的服务,我们还要在这个server{}里面配置django的服务。所以我们还要再加一个location。
第二个location里面,
try_files $uri @proxy_to_app 检查静态文件,如果不是的话就代理到应用。
下面应用做了哪些事情?设置代理头、请求的协议。这里我们可以去看一些文档。
我们看下gunicorn的官方文档。
proxy_pass http://app_server;配置成proxy_pass http://ck13_django:8000;为啥可以这么写,之前说过了,可以直接配成容器名(ck13_django)进行解析。端口是8000。这样子我们就做到了反向代理。
在etc/nginx/conf.d/defaultconf新增配置之后,需要重新启动。
然后我们直接云服务器域名:端口,是不是能直接访问啦。
那为啥我们之前云服务器域名:9321,是这个样子的呢。
那是因为你少了静态文件。
4. 部署前端项目
(1)打包前端项目
打包前端项目,会有一个dist文件夹。将dist文件夹拷贝到nginx容器中里的nginx文件夹中。
# 打包前端项目, 自动生成一个dist文件夹。
npm run build
此时我们需要将dist文件夹也要映射到nginx容器里,所以我们需要停止和删除nginx容器,重新去创建一个nginx容器
# 1.停止nginx容器
docker stop ck13_nginx
# 2.删除nginx容器
docker rm ck13_nginx
# 3.重新创建一个容器(将dist文件夹映射到nginx容器里)
docker run -d --name ck13_nginx -p 9400:80 -v /ck13/manual/nginx/conf.d:/etc/nginx/conf.d -v /ck13/manual/nginx/static:/usr/share/nginx/html/static -v /ck13/manual/nginx/dist:/usr/share/nginx/html/dist --network ck13 nginx:alpine
(2)配置nginx
1. 在default.conf(/ck13/manual/nginx/conf.d,也就是云服务器中的项目和nginx存放路径)中增加如下配置。我们需要再写一个server{}。
server {
listen 81; # 配置前端项目服务的监听端口
server_name localhost; # 配置域名(没有一样的端口,所以地址可以不管他)
root /usr/share/nginx/html/dist; # 配置文件根路径
location / {
try_files $uri $uri/ @router; #需要指向下面的@router否则会出现vue的路由在nginx中刷新出现404
index index.html; # 如果是 斜杠/的话 就会直接返回index.html
}
#对应上面的@router,主要原因是路由的路径资源并不是一个真实的路径,所以无法找到具体的文件
#因此需要rewrite到index.html中,然后交给路由在处理请求资源
location @router {
rewrite ^.*$ /index.html last;
}
}
2. 然后我们又需要重新启动一下nginx容器。为什么呢?因为我们需要映射上面配置文件中的81端口。
# 1.停止nginx容器
docker stop ck13_nginx
# 2.删除nginx容器
docker rm ck13_nginx
# 3.重新创建一个容器(将dist文件夹映射到nginx容器里)
docker run -d --name ck13_nginx -p 9400:80 -p 9500:81 -v /ck13/manual/nginx/conf.d:/etc/nginx/conf.d -v /ck13/manual/nginx/static:/usr/share/nginx/html/static -v /ck13/manual/nginx/dist:/usr/share/nginx/html/dist --network ck13 nginx:alpine
备注:如果是先重新启动nginx容器,后去修改配置文件的话(先走上述2再走1的操作的话),我们就需要重启nginx。
# 进入容器
docker exec -it ck13_nginx sh
# 重新加载
nginx -s reload
都配置完之后,我们去访问域名:9500,就跳转到了首页。