博客前端Shiro低内存部署 ✨
前天六点多,我的博客服务器挂了。尽管阿里云给我发了告警提示,但是丝毫没有用处。当我日常在我的互联网2C2G3M领地巡游,郎当哩个儿郎,发现只有主页可以看,其他的页面都是504 Gateway-Timeout,咚咚锵咚咚锵,看了看阿里云的监控,原来是内存泄漏,现在内存爆了,锵锵锵锵锵锵,让我看看是哪个坏蛋的锅,咚咚咚咚咚咚,咚不起来了,连不上ssh了。
已经不是一般的故障了,必须要出重拳,才能收回我的2C可用0G3M的领地了。
强制重启下,内存使用也降下来了,正好可以把我的博客前后端更新一下,我的部署参考了玖月的教程,具体是这个和这个,当然我上的是残缺版,能用就行。
使用docker更新后端很简单啊,不多赘述,总之叮呤哐啷地升级完成。更新前端就不太好了,build需要比较大的内存,上次的方法是用阿里云按量付费租个内存够大的机器,然后内网一顿传。可惜今时不同往日,我已经有了本地的ubuntu备用机了,何必涨阿里志气。
事实比较遗憾,如果要一股脑全部传过去,外网3M的小水管还是不太够用,何况我的网络上传速度又比较遗憾,难道重蹈覆辙?
阅读以下内容前建议先阅读Mix-Space部署最新前端Shiro
感谢Shiro项目使用的Next.js的先进特性,翻了翻项目的 next.config.mjs
,发现它配置了 output: 'standalone'
!这个简直是我需要的神兵利器!它会在 next build
之后,聪明地只打包那些真正需要的依赖文件(连 node_modules
都会来个“瘦身版”),然后一股脑儿塞进 .next/standalone
目录,出来的就是个超迷你的构建包!
赢
// 项目中的 next.config.mjs 长这样:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone', // 就是这行!
// ... 其他配置
};
export default nextConfig;
项目里还有一个打包脚本,可以自动化地打包 standalone
模式的输出,使其可以直接用于部署。
赢赢
#!env bash
set -e
CWD=$(pwd)
cd .next # 进入构建输出目录
rm -rf cache # 清理构建缓存
cp -r ../public ./standalone/public # 将 public 静态资源复制到 standalone 目录
cd ./standalone # 进入 standalone 目录
echo ';process.title = "Shiro (NextJS)"' >>server.js # 添加进程标题
mv ../static/ ./.next/static # 移动服务端必需的静态资源 (供 standalone server 使用)
cp $CWD/ecosystem.standalone.config.cjs ./ecosystem.config.js # 复制 PM2 配置文件
cd .. # 返回 .next 目录
mkdir -p $CWD/assets
rm -rf $CWD/assets/release.zip
zip --symlinks -r $CWD/assets/release.zip ./* # 压缩整个准备好的 .next 文件夹
脚本把优化过的 standalone
输出拿过来,再把 PM2 配置、静态资源这些“佐料”加上,最后变出一个 assets/release.zip
的压缩包,就可以方便地传输部署了。
赢赢赢
理论可行,接下来就是实操了。
开发机做什么
首先安装好pnpm,然后在项目根目录下运行
pnpm install # 或者 pnpm i
pnpm build
这时就会跑 next build
,然后噌噌噌噌地生成 .next
文件夹,里面就有我们心心念念的 .next/standalone
然后
bash standalone-bundle.sh
就噔噔噔噔端出一个 assets/release.zip
部署包。🥳
最后把这个压缩包发送到服务器上,开发机的任务可以说就大功告成了。
服务器做什么
首先要有适当版本的node.js与PM2,同时给够权限。
sudo mkdir -p /srv/shiro-app
sudo chown -R user:usergroup /srv/shiro-app # 给自己授权
cd /srv/shiro-app
sudo unzip /放压缩包的路径/release.zip
然后进入 standalone
目录, server.js
和 ecosystem.config.js
都在这里。
cd standalone
pm2 start ecosystem.config.js
这下真是大功告成了,不过之前部署一直出错,最后排查半天发现是写错了.env
里的域名,大失败。