笔记
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:多阶段构建一次改到位
内部这个 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 不值得。