墨穗app.notebase.cn
控制台
内容库
动态
管理
账户
U
用户
--
在线
v1.0.165 · 墨穗笔记
笔记

Notebase墨穗
静水流深,落墨成穗。

0笔记
0工具
30推荐

分类导航

按主题直达

编辑精选

站内用户贡献 · 真实笔记

最新收录

每日更新
继续浏览全部内容 →

笔记

0
加载中...

工具

0

此页用于记录用户反馈问题后的每一次改进

关于

笔记用法

“写笔记”支持四种格式——Word 文档、Excel 表格、Markdown、纯文本,起稿或二次编辑时都能随时切换,同一篇笔记想用哪种形态来记,都由你说了算。

md、txt、csv、json 这类纯文本则原样载入,不做多余加工。拿一张现成的表倒进来、改几笔、再导出去,等于白用一台免费的格式转换器。

要带走就在右上角点“下载”,可导出 PDF、Word、Markdown、Excel、TXT 等格式;列表卡片“⋯”菜单里,也有同样的下载入口。

工具用法

在“工具”页点“+ 上传工具”即可发布:填好名称与链接,再用 Markdown 把使用方法写清楚——能解决什么问题、怎么装、怎么用,比堆介绍实在。

要分发安装包就一并上传压缩包(ZIP、RAR、7Z、TAR.GZ,最大 35MB),别人在详情页一键下载;只放链接不带附件也可以。

工具按大家的收藏热度排序,好用的自然会被顶上来。发布后可在详情页或卡片菜单里编辑、下架。

隐藏笔记

写笔记时勾上“隐藏”,这篇就只存在于你自己的账号里:不进列表、不进搜索、不上首页精选,也不会出现在任何公开的页面,链接发给别人同样打不开。

适合放密码、草稿、日记这类只给自己看的内容;想公开,去“发布”打开它,把“隐藏”的勾去掉再保存,之后编辑会默认保持原状态,不会悄悄变回公开。

不想公开、只想临时给人看:点“分享”生成一条带密码和有效期的链接,到期自动失效,你也能随时撤销。

数据安全

你的内容会同时保存在多个副本上,系统定期做备份与完整性校验,再配合异地容灾机制:就算某台机器出问题,数据也不会丢,可以长期放心存放;特别重要的资料,仍建议你另外再留一份备份。

技术

全站跑在容器化、模块化的现代架构上,更新、部署、回滚都很快,扩展性和稳定性都按长期运营的标准来设计(Built for reliability, designed to scale)。

理念

这个网站最早只是一个人的笔记仓库,后来慢慢长成现在的知识中枢。设计上很克制——没有广告、没有追踪、没有推荐算法,只是干干净净地存放一些东西;既然做好了,就公开出来,万一有人用得上呢。

原则

不做大而全,不做平台梦,保持简单、保持克制、保持好奇。所有内容都由用户贡献、由用户维护:不会突然冒出付费墙,不会在角落塞广告位,也不会把你的数据卖给第三方。

更多

产品会持续迭代,站内日志页记录着每一次改动,改了什么都有迹可循;想了解这个站是怎么一步步走到今天的,翻翻日志就能看到来龙去脉。

举报

如果在这里看到涉嫌违规的内容,点对应卡片右侧的“举报”按钮就能提交,我们会尽快核实处理;也谢谢你花一点时间,一起把这里维护干净。

趋势

// 点击导航加载发现
归档
// 归档为空
最近浏览
// 暂无浏览记录
发布
// 加载中...
用户发布
// 加载中...
用户管理
// 加载中...
访问统计
// 加载中...
内容审核
// 加载中...
个人信息
// 加载中...
返回首页

Node 镜像从 1.1G 瘦到 126M:多阶段构建一次改到位

2026-09-02容器

内部这个 Node 工具后端的 Dockerfile 一直是我偷懒从网上抄的那种无脑写法:FROM node:20,整个项目 COPY 进去,RUN npm install 也不区分 dev 依赖,跑了一年多没人管,直到这次要打包成离线安装包发给客户内网。镜像 1.08G,客户那边导镜像、拷贝都要等半天,领导让我压一压,我才第一次认真看它到底胖在哪。

先查空间花哪了。docker images 里 node:20 那个基础镜像自己就 1.1G 上下,debian bookworm 那套带了几百个用不上的系统包和编译工具链;项目里 node_modules 装完 480 多 M,其中 typescript、eslint、@types/*、vitest 这些占了大半,全是构建期才用的东西。所以大方向就两条:基础镜像换小的、node_modules 只留运行时需要的。改完的结构大概是:

FROM node:20 AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY src ./src
COPY tsconfig.json ./
RUN npm run build

FROM node:20-slim AS runtime
ENV NODE_ENV=production
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev && npm cache clean --force
COPY --from=build /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/index.js"]

构建阶段用全量 node:20,跑 tsc 编译;运行阶段换 node:20-slim,依赖只装 dependencies。中间踩了一个坑:没直接上 alpine,因为这个服务用了 better-sqlite3 这种带原生模块的库,alpine 是 musl libc,npm 上没现成的预编译二进制,构建阶段还得现场装 python3、make、g++ 去编译,随便一个依赖版本对不上就翻车。slim 是 glibc,better-sqlite3 有 prebuilt,npm ci 直接拉二进制就行,省一大截。

再往下其实可以叠 distroless,运行镜像能再压到一百零几 M,但实际没全上:服务健康检查脚本要 shell 和 wget,distroless 里连 /bin/sh 都没有,得自己往镜像里塞 busybox,折腾半天收益就那二十 M,退回到 slim 收手。运行阶段的依赖安装我没用构建阶段现成的 node_modules,而是重新 npm ci --omit=dev 装一遍,多花一次安装时间,但干净可复现,而且依赖层不常变,BuildKit 有缓存,实际重 build 没慢多少。

几个数字对账:node:20-slim 基础镜像 235M,加运行时依赖和产物最终 126M,从 1080M 降下来差不多 88%。COPY 顺序也顺手调了,package.json 和 lock 文件放最前面,源码放最末,这样只改代码时依赖层能命中缓存不用重装;再配了 .dockerignore 把 node_modules、.git、dist、测试目录排除出构建上下文,docker build 上传的 context 从 500 多 M 降到 2M 以内,构建肉眼可见地快。想看具体哪层占空间可以用 docker history --no-trunc 镜像名,最大的那层一般就是某次 RUN 把临时文件、包管理器缓存留在了镜像里,对应补 apt-get clean、npm cache clean --force 能再挤一点。

中途我还量了下传输体积的差别:docker save 出来再 gzip,原来 380M 左右,瘦身后压到 60M 上下,客户那边用优盘拷、用内网传都快了很多,离线交付的体验完全不一样。层数也别图省事堆太多,一个 RUN 干一件小事再写五行是最容易把镜像搞臃肿的写法,能合并的 RUN 顺手合并;但过度合并会牺牲缓存命中,改一行代码整层重来。我一般把"装依赖"和"跑构建"拆成两层,这两个阶段变更频率完全不同,依赖层一个月动一次,源码层天天动,拆开才能让缓存各用各的。

有个细节差点翻车:build 阶段和 runtime 阶段如果 Node 大版本不一致,比如构建用 node:20 编译、运行用 node:18,有些语法和原生模块二进制会对不上,运行起来才报错。所以两个阶段的基础镜像主版本号我保持一致,都用 20,只差 -slim 后缀。还有 npm ci 要求 package-lock.json 必须存在且和 package.json 匹配,CI 里如果经常手动 npm install 把 lock 文件搞乱,npm ci 会直接失败,报错会提示 lock 文件与 package.json 不同步,这时候别硬删 lock 重装,先想清楚是不是有人没走 npm install 的标准流程。node_modules 里如果有平台相关的二进制,换基础镜像后最好重新装一遍依赖而不是直接 COPY,否则 glibc 和 musl 的差异会让模块加载直接报错。这些坑一次踩完,后面再出镜像就顺了。

瘦身优先级按我这次的经验排:多阶段构建是地基,先搭这个再谈换基础镜像,然后剔 dev 依赖、清包管理器缓存,distroless 属于有洁癖才上,别一上来就折腾它,普通内部服务省那几十 M 不值得。

相似推荐
服务器重启后 Docker 容器全没起来、顺序还乱?自启加依赖一次理清Docker 日志把磁盘写满,网站突然全挂?截断加限容一次配好docker compose 里 ${VAR} 到底读的哪个环境:.env、shell、env_file 优先级备忘容器里是普通用户,往 -v 挂的目录写文件老报 Permission denieddocker stop 老等满 10 秒被强杀:多半是进程没接 SIGTERMbuildx 打多架构镜像:arm64 在 x86 上构建,一路绿灯到部署才炸
编写使用方法
Markdown 格式 · Ctrl+Enter 确定
0 字新建笔记
欢迎回来
登录你的墨穗笔记账户
忘记密码?
还没有账户?立即注册
创建账户
注册你的专属墨穗笔记
已有账户?去登录
找回密码
输入注册邮箱获取验证码
返回登录
请输入图片中的验证码以继续注册
加载中...
取消
新建收藏
手动添加你喜欢的内容
取消
编辑头像与昵称
上传新头像或修改你的显示昵称
支持 JPG/PNG,最大 2MB
取消

问题反馈

隐私提醒

取消
编辑工具
受控分享
为这篇笔记生成限时 / 带密码的临时链接
关闭