ubuntu部署小笔记-采坑
ubuntu部署小笔记
- 搭建前端+控制端+后端
- 前端
- nginx反向代理
- 使用ubuntu部署nextjs项目
- 问题一 如何访问端口号
- 配置
- 后台运行该进程
- pm2
- 问题二 包体过大
- 生产环境下所需文件
- 问题三 部署在vercel时出现的问题
- 需要魔法
- 访问后端api时,必须使用==https==协议
- 电脑端访问正常,手机端出现异常
- 控制器
- 部署
- 路由正常,但是刷新后提示404的问题
- 相对路径问题
- 后端
- 部署
在实际将项目部署到linux服务器(ubuntu)的过程中遇到的一些小细节的问题
在这里记录一下
搭建前端+控制端+后端
找到一个大佬开源的项目nextjs+vite+java,是一个用起来功能蛮多的开源项目,蛮好用的,很多实用性的功能。前端使用nextjs,控制器使用vite,后端使用java,想试着在linux上部署
前端
nginx反向代理
题外话
之前一直没有去摸这方面相关的技术,因为一直不是很理解,也没有想去花时间接触,现在因为需要项目搭建,所以特意用了nginx来部署项目,也是为了提高自己的能力
那么啥叫反向代理,经过最近差不多一个星期的接触和使用,我的理解其实就像大家熟知的那样,是一个类似中转站的东西,将外部发送过来的访问和请求,以一定的规则,去访问内部的资源和项目。
但是这和使用apache2或者tomcat之类的又有什么区别呢,不也是外部通过ip或者域名的方式,访问到我们绑定的项目路径吗
其实还是有一些细微的差别,但我不知道能不能解释清楚。就我的认知,反向代理可以通过内部转换的方式,将外部的访问进行识别和处理,然后转发给内部的指定服务
具体的例子就是
我有一个前端项目 ,域名为www.xxx.com。这是我的一个主页
同时我有一个配套的前端管理项目,我希望也在这个域名下通过www.xxx.com/admin的方式进行访问
如果是我之前的能力,我的解决方式有两个
- 在这个域名上申请多一个二级域名,比如admin.xxx.com,然后将这个二级域名绑定到前端管理项目的路径上,然后进行访问
- 在前端项目的public路径下将前端管理项目拉进去,然后通过www.xxx.com/public/admin的方式进行访问
毋庸置疑,这两个方式都不能实现我的需求,但是,反向代理就可以实现
通过解析域名的后缀,也就是admin,根据配置转发到指定的服务,也就是前端管理项目
并且他可以通过配置不同的参数,将同一个访问下发转发到不同的服务器上,从而减轻服务器的压力
好的说了这么多,实际我在使用的过程中都遇到了哪些问题呢
使用ubuntu部署nextjs项目
也是第一次接触nextjs这个语言,听说是以react为基础开发的, 当然react我也没了解过
这个不重要,主要先讲部署的东西
nextjs通过npm指令进行依赖安装,调试和打包
npm install //这是安装
npm run dev //这是调试环境
npm run build//这是打包
npm run start//这是生产环境
问题一 如何访问端口号
配置
按照之前我部署前端的经验,就是打包,然后将打包出来的上传到服务器上,然后通过路径进行访问
但nextjs不同,他需要通过npm run start指令启动,并且自己占用端口号。这就把我难住了,我只试过直接访问静态资源的部署,这种端口号的可咋整,难道要我直接暴露端口号给用户吗,但是www.xxx.com:9003这种访问真的太丑了…于是我了解了一下发现apache和nginx都是支持转发端口号的,当程序员这么久也是才知道的Orz。这也就是反向代理的作用之一,当然不是只有nginx才有,apache,tomcat我相信都会有这个功能,只不过谈起```反向代理···脑子里第一反应就是nginx,所以就用了他
在哪里配置呢
在etc/nginx/下的nginx.conf或者sites-available下的default两个文件中其中一个配置下面的信息都行
我建议是在nginx.conf文件下配置,毕竟你可以少进入一个目录,而且这个文件名也一目了然
不过要注意的是nginx.conf文件
下需要在http{里配置下面的server信息}
server {# Nginx监听443端口(标准HTTPS端口)listen 443 ssl;# server_name _; # 通用域名server_name xxx.xxx.xxx; # 你的域名# SSL证书配置ssl_certificate ;//如果有的话ssl_certificate_key ;//如果有的话location / {proxy_pass http://localhost:9001; //通过转发的方式访问nextjs项目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;}# 后端APIlocation /api {# rewrite ^/api/(.*) /$1 break; # 去掉/api前缀proxy_pass http://localhost:9003;//通过转发的方式访问后端项目(java)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;}location /static/{root /var/www/;autoindex on; }}
后台运行该进程
由于直接执行npm run start的话,当我们远程连接关闭后,进程就会被自动kill掉了,所以我们需要将进程放在后台运行
有两个方案,一个是nohup,下面运行jar包会详细讲,这里说另一个方案
pm2
pm2好像是专门用来管理npm相关的项目的工具
pm2 start npm --name 项目名(自定义)--port=端口号(不写就默认使用3000)
命令大概是这样,还可以设置对应的运行内存啥的,有兴趣可以自己了解一下
运行了之后也可以实时查看日记
输入下面的指令就可以查看了
pm2 log 前面自定义的项目名
问题二 包体过大
回到正题,nextjs项目在build之后,包体非常大,就我目前在用的打包出来有768m,说实话,这比我用unity开发网页版的游戏都大了4、5倍…
然后因为包体太大了,我就尝试在服务器端直接拉去项目源码,然后在服务器上跑npm run dev
这一dev,没什么问题,npm run start
也没什么问题,但是用户一访问项目,开始编译的时候,2核2g的服务器直接就宕机了…一开始我要还以为是我的指令有问题,排除了好久…
原因就是npm run build
对读写性能的要求很大,在自己的电脑上处理没什么问题,大不了等多一会,但是云服务器上的配置撑在不了这么大的读写量,所以就直接宕机了…
无奈,于是只能乖乖的本地npm run build
后部署到服务器端,然后执行npm run start
好了,这下可以通过端口访问了,然后再用nginx转发的方式,将外部访问转到内部的这个端口号就行了
当然其中有一些小细节需要注意
生产环境下所需文件
.next
// npm run build 指令后生成
package.json
、package-lock.json
// 运行项目所需配置文件
当然只有这三个不出意外的话也是不行的, 因为npm run start执行时,会需要next相关的依赖
所以要么在项目根目录下执行npm install配置项目所需的环境依赖,要么就全局配置一下相关依赖。我是项目根目录中install的,这样有一个坏处就是生成的node_module文件也不小,我的是400+m,一个400m一个700m,好家伙一个前端项目就要1g了…前端发展的太快了…
如果以上操作都没问题的话,那么你的项目应该最终也能跑起来了
问题三 部署在vercel时出现的问题
原先因为包体过大在ubuntu上无法正常访问,所以通过github的方式在vercel上进行了部署,vercel有一些坑
vercel有什么好处,第一是免费,第二是一键帮你部署项目。只要关联github,选择对应的项目,vercel就会一键帮你构建和部署,只需要访问他提供给你的项目域名即可
需要魔法
vercel部署的项目需要魔法
才能访问,有梯子的话访问速度还蛮快的说实话。当然,你也可以通过cloudflare进行cname的设置将国内的域名绑定到vercel提供的域名上,毕竟有的白嫖谁不想呢是吧
但是
经过实际体验,就算通过cloudflare转发,访问速度也是完全看cloudflare的,时快时慢,体验非常不好…所以这也是为什么我想最后还是部署在自己服务器上段原因,
访问后端api时,必须使用https协议
http他是不给调用的,而且有些即使是https的图片资源他也无法正常加载
有一个投机的办法,如果你的域名还没有备案通过的话,可以先去ssl申请免费证书,然后给服务器上的nginx里配置后端服务的ssl文件, 虽然ssl是给域名准备的,不过还是能访问的,只是前面会提示你依旧是不安全的内容
电脑端访问正常,手机端出现异常
部署项目后在电脑端没问题,能跑通,但是在手机端就是怎么都调用不到后端的数据
这个问题也是排查了很久才发现的,原因就是因为上面的投机取巧的方式,https证书在国内浏览器上应该是有处理的,不安全的直接就给你拦截下来了,所以在手机端上的任何浏览器都访问不了(微博内置的可以打开,他会提示你https不安全,是否继续访问,也是这个提示才让我知道问题所在;不过这里也有一个问题,我后面用备案过的域名申请的ssl证书,在微博里打开项目他也提示不安全…真是奇了怪了hhh)
然后我就试着用已经备案过的域名去申请一个ssl,然后在nginx上绑定这个域名和对应的证书文件,发现手机端也正常了
控制器
控制器使用的是vite,这个说实话我也不了解,不过这个也可以用npm进行操作
浅浅的看了一下,直接跳转如何部署项目
vite通过指令
npm install
安装依赖
然后通过npm run dev
进行调试
npm run preview
进行预览
npm run build
进行打包
vite打包出来不需要额外的启动,直接访问项目路径即可
这一点还是挺好的
你只需看把打包出来的dist
文件上传到服务器即可
nginx配置一下访问路径
部署
server {listen 80 ;server_name _; # 或者你的域名# SSL证书配置# ssl_certificate /home/ssl/xxx.pem;# ssl_certificate_key /home/ssl/xxx.key;root /var/www/redfanswebadmin/dist;index index.php index.html index.htm;location / {try_files $uri $uri/ /index.html;}location ~ /\.ht {deny all;}}
路由正常,但是刷新后提示404的问题
这是由于没有在localtion /下配置下面的这行代码,导致项目内路由正常,但刷新时,因为没有配置从index.html进行访问,直接去访问项目资源,导致了404的问题
location / {try_files $uri $uri/ /index.html;}
相对路径问题
原先我是想在nginx配置文件中已经有的nextjs项目里添加一个/admin的转发,然后少申请一个二级域名的,但是vite项目中的一些资源文件和路由,使用的都是相对路径,也就是说,如果我用admin转发到了vite项目,由于相对路径的问题,很多的资源他访问的位置就不是vite的路径了
举个例子就是
vite项目中加载一些css和js的文件
使用的是/assets/...css
,如果使用/admin转发的话,他就会在nextjs项目的路径中去找对应的/assets/...css
文件,这显然是不对的,如果要改的话,需要在vite项目中一个一个找所有用了相对路径的配置,这会比较麻烦,所以就放弃了这个方式
当前做法
- 申请二级域名
- 在nginx中配置该二级域名以及对应的vite项目的资源路径
后端
后端使用的是java,我们的老熟人了,这个因为用了不少,所以基本没遇到什么问题
部署
- 在idea中通过maven的package命令直接一键生成jar包
- 上传到服务器,服务器需要有java
2.1 用tomcat运行(我没用)
2.2 使用linux的nohup指令后台运行
nohup java -jar jar包路径/xxx.jar &
后面的&就是后台运行的意思,不加的话就是远程连接的时候能用,关闭了这个指令就不执行了,所以是必须要加的
相关指令
nohup执行后会返回一个进程号,不需要的时候就用下面的指令加提供的进程号kill掉就行
kill -9 端口号
当然一般人也不会去记录这玩意儿,所以可以用下面的指令去找相关的服务器的进程号
ps -ef|grep 服务名(java,apache2,nginx等)
不过这样运行的话,你在jar包中设置的是什么端口号,那就是什么端口号,不能修改了
怎么查看日志,每个nohup执行后没有特别配置的话都会在输入命令的当前目录下生成nohup.out文件,可以通过下面的指令去查看实时日志
tail -f nohup.out
由于都是用的纯命令行,所以也就没有什么截图的必要了,指令真的只能多打才能记得住…
题外话
- 开源项目中也存在一些问题,如上传图片的路径需要设置,后台也需要配置,否则会出现上传后在前端无法访问的情况。其他问题暂时没有。哦开源的作者部署前端项目使用的是宝塔,我在win上安装了下宝塔,在运行前端项目时提示了一些python相关的异常导致无法正常运行,所以就没用宝塔了…
- nginx可以和apache之类的同时跑通,不过需要确保端口之间没有冲突,比如nginx先启动,默认占用了80端口,你的apache就得在配置文件中将80端口注释掉,否则apache会无法正常启动。然后应该怎么使用呢,举个例子:
2.1 nginx配置了一个域名www.xxx.com,指向apache中的其中一个服务(apahce中通过占用端口8888访问某个项目),nginx只需要在配置域名的server中的proxy_pass中输入localhost:8888,那么用户在输入www.xxx.com域名时,niginx就会通过转发的方式,将用户路由到apache中的8888端口号对应的项目。
2.2 当然这样有点多余,实际上你只需要在nginx中直接配置就行了。不过总会有需要这么用到的时候,所以就多提一下~ - 另外,部署之后,基本国内的app中内置的浏览器都能正常打开运行nextjs项目,唯独google浏览器不行…具体原因未知,一访问就提示client error之类的,然后再刷新也只能访问到网页的一些静态资源, 调用不到后端的接口。有遇到相同问题但解决了的大佬可以评论区留言解惑Orz
历时不到一个星期的时间,总算是成功将项目部署到了自己的服务器上,学习到了很多以前没接触过的知识和技术,学无止境…
也要感谢ai,基本都是边问边改的hhhhh