场景重现:
由于现在流行前后端分离的部署方式,但是按照正确方法部署(如何部署可参考:)之后,发现明明前后端都部署好了并且运行成功,但是前端发送的请求都是404。明明在vue项目中配置了跨域的相关设置:
ps:本地配置跨域请参考:什么是跨域?如何解决跨域问题?-CSDN博客
明明没问题,为什么就是发不过去呢,这是因为在本地环境下,这个配置是有效的,但是执行npm run build之后,并不会对这部分打包,也就是说即使你本地已经配置好了,但是打包好的dist文件里面并没有这部分,这就需要配置nginx,通过nginx代理到后端的端口。
话不多说,我们直接看如何操作。
开始解决:
首先我们检查nginx是否启动,输入:
docker ps
可以看到是正常启动的,然后我们进入容器内部:
docker exec -it nginx bash
注:nginx为你的容器名,也可以使用容器id,成功进去之后,显示容器id:
如果显示一个类似于:is restarting的错误,反正就是没进来,提示有一个error,那就执行:(成功进来就不用管了,跳过就行)
docker stop nginx
docker start nginx
重新启动容器就行,如果还是不行,那就是你的配置或者run命令出现了问题,直接stop容器,然后docker rmi nginx重新执行一遍run命令即可,本人的run命令如下,可作为参考:
docker run -d -p 80:80 --name nginx -v /home/nginx/dist:/usr/share/nginx/html --restart=always nginx
进来容器之后,我们进入配置文件目录:
cd /etc/nginx
可以看到,里面就有nginx.conf,不过我们的目标不在这里,而是前面的conf.d,不过我们也可以看一下nginx.conf里面是什么:
ps:如果是第一次进入容器,需要先执行下面两条命令下载vim编辑器
apt-get update
apt-get install vim
下载完成(下载会比较慢,不用着急,下载过程大概需要五分钟左右)之后直接输入:
vi nginx.conf
回车进入配置文件:
其实你可以看到,他关于server的设置都是在conf.d下的*/conf文件中
然后我们按下键盘的esc键,输入:wq退出即可(包括冒号)。然后我们进入conf.d中
可以看到只有一个文件,我们输入:
vi default.conf
进入配置文件
你们进来是没有红框里面的内容的,这也是需要加进来的配置:
location /api/ {
proxy_pass http://localhost:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
切记把api替换成你前端代理的地址(一般人都是api),然后把localhost换成你服务器的地址,尽量不要用localhost。
location在监听到前端发送请求之后,如果你的路径中带有api,就会自动转发到你指定的地址,这样就实现了nginx的反向代理,同时,你也可以实现多端的发送,可以设置多个location,可以代理到多个后端接口。设置完成之后保存退出即可,按下esc,输入:wq(包含冒号)。重启nginx即可:
docker restart nginx
查看是否启动成功:
docker ps
总结&可能出现的错误
最后,修改配置文件的时候注意一定要细心,比如 location /api/,location后面是有空格的,最后面的/不要丢掉,服务器路径后面的/也不要丢掉,后面的分号也必须要有,分号(;)代表语句的结束,没有分号就会连着执行两条语句,就会报错。
最后的最后,我们来分析并解决一下你可能会出现的问题,或者已经出现了的问题。
首先就是最后重启nginx之后,发现输入docker ps发现没有nginx,然后输入docker ps -a,发现有nginx这个容器,但是没有端口。这时候可以输入:
docker logs nginx
查看nginx的启动日志,你发现最下面报了好几个error,针对不同的错误去做不同的解决方式,但是,由于你只进行了本文的conf配置文件配置修改,那就是说只有一个原因:你的配置文件写错了。由于你的nginx启动不了,你也没有办法进入容器重新查看配置文件,你只能docker rmi nignx,然后重新执行一遍run命令。然后重新配置一遍,这次一定要检查好有没有输错,缩进分号有没有按照要求来。
如果是ps发现跑起来了,但是没有端口,那就是端口被占用了或者是其他一些原因了,这个很容易解决,端口被占用,kill掉就可以,其他原因大概率也是nginx本身的原因,看一下是不是你的run命令写错了,stop掉然后rmi之后重新run一遍吧。
最后就是挂载的问题,我建议把nginx的html挂载到主目录的某个文件下,但是不建议挂载配置文件,第一是我认为配置文件一般只需要配置一次即可,特别是服务器上的,第二是如果挂载文件和被挂载文件不同的话,是有一定可能出现问题的,第三也是为了安全性,还是让他就在容器里面呆着吧。
作为一个加起来只有七个月开发时间的全栈工程师,还没入门,不过好像依稀已经可以看得到远方的门槛了,我还有很长的路要走,本文也是我的一点经验,文章略显稚嫩,希望各路大神可以指点一二,也预祝大家从此没有bug,在全栈和架构师的道路上越走越远!