[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"site":3,"post-cong-da-bao-shang-chuan-dao-push-ji":59,"related-cong-da-bao-shang-chuan-dao-push-ji":85},{"name":4,"url":5,"description":6,"bio":7,"avatar":8,"skills":9,"tools":16,"social":34,"hero":47,"heatmap":52,"icp":55,"police":56,"policeIcon":57,"shortName":58},"时过境迁技术笔记","https:\u002F\u002Fhsgjq.top","一个记录前端与 Node 实践的个人博客，内容围绕 Vue、Nuxt、NestJS 与工程化展开，附源码级的原理笔记。","一名热爱技术的全栈开发者，专注 TypeScript 与 Web 工程化，习惯把踩过的坑和思考记录在这里。","\u002Fuploads\u002Fc485c101-179e-48db-96d1-238693784c38.jpg",[10,11,12,13,14,15],"TypeScript","Vue 3","Nuxt","NestJS","Node.js","工程化",[17,23,28],{"items":18,"title":22},[19,20,21],"Cursor","Git","Chrome DevTools","开发工具",{"items":24,"title":27},[25,26],"Vite","npm","构建工具",{"items":29,"title":33},[30,31,32],"Docker","CI\u002FCD(GitHub Actions)","Vercel","部署运维",[35,39,43],{"href":36,"icon":37,"label":38},"https:\u002F\u002Fgithub.com\u002Fhsgjq","github","GitHub",{"href":40,"icon":41,"label":42},"2971861643@qq.com","mail","邮箱",{"href":44,"icon":45,"label":46},"\u002Frss.xml","rss","RSS",{"lines":48,"subtitle":51},[49,50],"人生若只如初见，","何事秋风悲画扇。","《木兰花·拟古决绝词柬友》",{"enabled":53,"platform":37,"username":54},true,"hsgjq","桂ICP备2024046985号","桂公网安备45011002000103号","\u002Fuploads\u002F72c67ef3-bc86-4b64-b0df-0aba71065050.png","时过境迁",{"slug":60,"title":61,"excerpt":62,"date":63,"updatedAt":64,"tags":65,"content":66,"series":67,"seriesIndex":68,"seriesNav":69,"prev":79,"next":82},"cong-da-bao-shang-chuan-dao-push-ji","从打包上传到 push 即上线：把 CD 接通","私有仓库的镜像包默认也是私有的，健康检查的探测地址在宿主机有 nginx 时会打错地方。两处都是配好之后才验出来的。","2026-10-02","2026-10-19",[30,15],"上线之后每次发版都要在本地 git archive 打包、scp 上服务器、解压、改端口、重新构建。1.9G 的机器构建前端要动 swap，一次十几分钟。\n\n接通 CD 之后这些都没了：推 main，CI 全绿后自动构建镜像推到 GHCR，SSH 到服务器 pull + up，健康检查不过就回滚到上一个版本。\n\n配置里有两处是配好之后才发现会坏事的。\n\n第一处是健康检查的探测地址。部署脚本原本 curl http:\u002F\u002F127.0.0.1\u002F，看起来天经地义。但这台机器上 80 端口是宿主机的 nginx，站点块的 server_name 是域名，Host 是 IP 的请求命不中它，返回 404。于是健康检查永远不通过，每一次正常发布都会被判定失败并自动回滚——回滚还是\"正确地\"执行了我没打算让它执行的动作。\n\n改成从 .env 里的端口配置推导，直接打 gateway 容器：\n\n```bash\nGATEWAY_PUBLISH=127.0.0.1:8081:80   # → 探测 http:\u002F\u002F127.0.0.1:8081\n```\n\n第二处是镜像仓库的权限。仓库是私有的，GHCR 上的包默认跟着私有，服务器 pull 会被直接拒绝。要在服务器上先 docker login ghcr.io，用一个只有读包权限的令牌。\n\n端口配置也一并收进了 .env。以前 gateway 端口是就地改 compose 文件，重新上传代码就被仓库里的 80:80 覆盖回去，每次都要重跑那条 sed。现在是 ports: [\"${GATEWAY_PUBLISH:-80:80}\"]，值在 .env 里，代码更新不会碰它。\n\n第一次跑之前我卡了两件事没做，都会导致发布失败：端口没配进 .env（那样 up 会去抢 80，把站点弄停），以及没登录 GHCR（拉不到镜像）。顺序是先配这两件，再推代码。\n\n推上去之后 CI 跑一轮，CD 接着跑；构建在 runner 上完成，服务器只负责拉和起。那台 1.9G 的机器从此不再参与打包，构建内存墙这件事跟着消失了。","工程化与部署",13,[70,74,78],{"slug":71,"title":72,"seriesIndex":73},"tu-pian-dao-di-cun-na-cong-dui","图片到底存哪：从对象存储的念头回到自建目录",11,{"slug":75,"title":76,"seriesIndex":77},"swap-dui-shang-xian-he-gou-jian-nei","swap、堆上限和构建内存墙",12,{"slug":60,"title":61,"seriesIndex":68},{"slug":80,"title":81},"shang-xian-na-tian-yu-ming-zheng-shu","上线那天：域名、证书，和一条我打错的 IP",{"slug":83,"title":84},"dian-xiang-mu-ye-mian-jiu-si-yi","点「项目」页面就死：一次客户端无限重定向",[86,92,98,102,108],{"slug":87,"title":88,"excerpt":89,"date":90,"tags":91},"jian-li-de-xie-gang-hui-bian-cheng","键里的斜杠会变成冒号：清缓存清了个空","按源码里的分组名去匹配存储键，结果一条都没删掉，接口还回 200。返回一个可被证伪的数字，这类问题当场就能发现。","2026-09-30",[12,15],{"slug":93,"title":94,"excerpt":95,"date":96,"tags":97},"wo-ba-compose-de-override-xie-cuo-zhan","我把 compose 的 override 写错，站点停了二十分钟","ports 是追加不是替换，合并之后 80 端口撞了；而 up 失败前旧容器已经被换掉。配置检查命令的输出格式也骗了我一次。","2026-09-03",[30],{"slug":75,"title":76,"excerpt":99,"date":100,"tags":101},"swap 让构建不被杀但变慢，抬堆上限让 Node 敢用更多内存，两件事要一起做。试过的几个数字和哪个最后成了，都写在里面。","2026-08-20",[30],{"slug":103,"title":104,"excerpt":105,"date":106,"tags":107},"1-9g-nei-cun-de-fu-wu-qi","1.9G 内存的服务器上，nuxt build 在第 36 秒被杀","V8 堆耗尽直接 SIGABRT，日志里只有一句低内存提示。先分清是被系统杀的还是自己崩的，再决定加内存还是加 swap。","2026-08-08",[30],{"slug":71,"title":72,"excerpt":109,"date":110,"tags":111},"算了一下流量和成本，先放在自己的卷里，把上传路径和访问路径分开设计，将来要换存储只改一处。","2026-07-14",[15]]