从零到一做了一个极简的文件分享工具,并上架了Github镜像站
一句话介绍:我写了一个Docker程序,叫CountShare——上传文件或文件夹,生成分享链接,别人下载后你能看到下载次数。管理员可以设置密码、有效期、下载次数。整个系统不需要登录,不需要数据库,轻量到极致。
一、为什么要做这个东西
前段时间写了个离线PDF工具箱,刚开始用飞牛NAS分享,能够设置到期时间、密码、可访问次数,生成的链接类似于“https://share.fnnas.net/s/1e39b43bd5b24dXXXX”,是飞牛的域名,分享出去也方便,唯一的缺点就是看不到下载次数。

我把这个链接放在公众号的自定义回复里,别人回复“pdf”就可以自动获取下载链接,但是公众号后台没有下载统计,我不知道这个工具有没有被人下载,更别说被下载了多少次。

后来换了可道云,终于能看到下载次数了。

但整个系统太庞大了,相册、插件管理、Icloud……俨然是一个完整的操作系统了,我只想分享一个文件而已。

问了万能的AI,知道了另外几个专门分享文件的Docker镜像,分别是Cloudreve、tmpshare、Pingvin Share X,但是无一例外,体积都不小。
• Cloudreve:1.2GB
• Pingvin Share X:555MB
• 可道云:842MB,还得配套装一个MySQL(再加558MB)

我的需求其实就三条:
1. 往服务器扔一个文件,别人能下载。
2. 我能看到这个文件被下载了几次。
3. 不用注册、不用登录、不用配数据库。
找了一圈现成的 Docker 镜像,要么功能过剩,要么界面太复杂,要么不支持下载计数。
最后想通了,既然没有合适的,干脆自己做一个,最终占用体积是129MB。
─────────────────────
~15MB Alpine Linux 用户空间(相当于一个迷你 Linux 系统)
~95MB Node.js 运行时占用的空间
~1MB CountShare 代码
~18MB Docker 文件系统开销
─────────────────────
二、怎么做出来的
说实话,我之前从没写过Docker程序。
但有了AI之后,我发现写代码这件事变得不一样了——你不需要会写,你只需要会问、会判断方向、会提要求。
整个开发过程大概是这样的:(注,我使用的是网页版的元宝,提问后手动把代码复制出来测试,没有使用Codex、Trae等自动化编程工具。)
第一步:跟AI描述需求
我把想法告诉AI:"我想要一个极简的文件分享工具——往目录里放文件,别人能下载,我能看到下载次数。不用登录,不用数据库。"
AI听完,给我出了一套方案:用Python写主程序,在Docker里装一个轻量Python Web框架。我看了眼Python基础镜像的体积——上百MB。虽然功能能跑,但我觉得还是太大了。
第二步:换路线,压体积
我让AI重新想一个更小的方案。AI说:"那用Node.js吧,纯内置模块,连npminstall都不需要。"
我追问:"真的零依赖?"AI确认:Node.js自带的http、fs、path模块足够写一个Web服务器,不需要装任何第三方包。
于是技术路线定下来了:Node.js + 纯内置模块 + Alpine Linux 基础镜像。
第三步:确定文件结构
整个程序最终只需要这3个文件:
1.app.js ← 主程序,所有逻辑都在这里(路由、文件扫描、下载计数、密码验证)
2.public/admin.html ← 隐藏的管理页(文件设置、下载记录)
3.Dockerfile ← 构建镜像的指令,基于 node:20-alpine
就这些。没有 package.json,没有 node_modules 文件夹,没有数据库配置文件。
第四步:一个一个功能磨出来
我没有直接让 AI "一次性写完",而是一点点加需求,每次跑起来看看效果,不对就改。
我在本地新建一个文件夹countshare,使用cmd进入命令行模式,输入node app.js,就可以开始测试了。

第五步:打包成 Docker 镜像
新建一个文件,名字为Dockerfile,内容为:
FROM node:20-alpine
RUN apk add --no-cache zip
WORKDIR /app
COPY app.js .
COPY public/ ./public/
VOLUME /files
VOLUME /data
EXPOSE 8000
CMD ["node", "app.js"]
构建完,在服务器上实际占用129MB(因为Node.js运行时本身占大头)。对比Cloudreve的1.2GB、可道云的842MB,这个体积我很满意。
第六步:上架GitHub并自动构建
代码上传到GitHub后,我让AI写了一个GitHub Actions工作流文件(.github/workflows/build.yml),配置好之后,每次push代码或发Release,GitHub都会自动构建镜像并推送到GHCR,全程不用手动操作。
回头看,整个过程中我写的代码行数是零。
但每一个功能决策、每一次"这个体验不好要改"、每一轮跟AI的对话,都是我在主导。
AI是执行者,我是产品经理兼测试工程师。
这种"不懂代码也能做出能用的东西"的体验,是这篇文章最想分享给大家的——你不需要成为程序员,你只需要知道你想要什么,然后学会跟AI把需求讲清楚。
三、做好后长什么样
1.管理页(隐藏路径,只有管理员知道地址):
页面分为三个区域:
1.文件列表:显示`/files`目录下的所有文件和文件夹,支持上传、新建文件夹、重命名、删除。每个文件或文件夹右侧都有一个「分享」按钮。
2.分享列表:显示所有已创建的分享链接,包含路径、状态(正常/已过期/次数用尽)、密码有无、有效期、下载情况(已下载/可下载)。支持复制链接、修改设置、取消分享、批量取消。
3.下载记录:显示下载时间、文件名、IP、浏览器型号,可按分享链接筛选。
所有数据一目了然,不需要进数据库查。

2.公开下载页:
文件分享:显示文件名、大小、已下载次数、有效期/限制(如有),点击「下载文件」按钮即可下载

文件夹分享:表格形式显示该文件夹下的所有文件,每个文件可单独点击下载,也可点击「打包下载全部」一键下载整个文件夹的zip压缩包

有密码的分享:访问时会先显示密码输入框,输入正确密码后才能查看和下载

四、怎么获取和使用
代码写好后,我把它放到了 GitHub 上,然后用 GitHub Actions 自动构建镜像并推送到 GHCR,任何人都能拉取。
1.拉取程序
命令为:
docker pull ghcr.io/wallechfox/countshare:latest
国内用户可以用公共加速镜像,速度快很多,比如:
docker pull ghcr.nju.edu.cn/wallechfox/countshare:latest
2. 启动容器
拉取后运行:
docker run -d
--name countshare
-p 8000:8000
-v /www/countshare/files:/files
-v countshare-data:/data
-e ADMIN_PATH=my-secret-admin
--restart unless-stopped
ghcr.io/wallechfox/countshare:latest
3.查看日志获取管理页地址
启动容器后,查看启动日志获取管理页地址:
docker logs countshare
输出示例:
========================================
CountShare running
FILES_DIR = /files
DATA_DIR = /data
PORT = 8000
管理页 : http://localhost:8000/a3f8k2d1e5f6
========================================
如果设置了ADMIN_PATH=my-secret-admin,管理页地址则为 http://localhost:8000/my-secret-admin。
4.访问管理页
在浏览器中打开管理页地址(如 http://你的服务器IP:8000/a3f8k2d1e5f6),你会看到三个主要区域:
文件列表:显示 /files 目录下的所有文件和文件夹
分享列表:显示所有已创建的分享链接及其状态
下载记录:显示所有文件的下载历史
5.上传文件或新建文件夹
在「文件列表」区域顶部,有三个操作按钮:
上传:点击后选择本地文件,上传到当前目录
新建文件夹:在当前目录创建一个新文件夹
刷新:刷新文件列表
你可以像使用文件管理器一样,点击文件夹名称进入子目录,点击面包屑导航返回上级目录。

6.创建分享链接
在文件列表中,每个文件或文件夹右侧都有一个「分享」按钮,点击目标文件或文件夹的「分享」按钮,在弹出的对话框中配置分享参数:
密码(可选):设置访问密码,留空则无需密码
过期时间(可选):点击「1天/3天/7天」快捷按钮,或手动选择日期时间
最大下载次数(可选):设置允许下载的总次数,留空则不限制

点击「确认分享」,系统会生成一个 6 位随机 ID 的分享链接,示例:http://你的服务器IP:8000/s/abc123
7.管理已创建的分享
在「分享列表」区域,你可以:
查看所有分享:列表显示路径、状态(正常/已过期/次数用尽)、是否有密码、有效期、下载情况
复制链接:点击「复制」按钮,链接会自动复制到剪贴板,按钮会短暂变为「✅ 已复制」
修改设置:点击「设置」按钮,可修改密码、有效期、最大下载次数
取消分享:点击「取消」按钮,该分享链接将立即失效
批量取消:勾选多个分享项,点击「批量取消」一次性取消多个分享

8.查看下载记录
在「下载记录」区域,默认显示所有文件的下载记录(按时间倒序),每条记录包含:下载时间、文件名、下载者 IP、浏览器型号。
可通过下拉菜单筛选特定分享链接的下载记录。

9.分享链接的访问效果
将分享链接发给别人后,对方打开会看到:
文件分享:显示文件名、大小、已下载次数、有效期/限制(如有),点击「下载文件」按钮即可下载
文件夹分享:显示该文件夹下的所有文件列表(表格形式),每个文件可单独点击下载,也可点击「打包下载全部」一键下载整个文件夹的 zip 压缩包
有密码的分享:访问时会先显示密码输入框,输入正确密码后才能查看和下载
五、写在最后
这是我第一次独立做一个 Docker 程序并发布到公共镜像仓库。
从“想找个现成的”到“干脆自己写一个”,从“完全不懂 Docker”到“成功上架 GHCR”,整个过程大概花了一个周末。实际开发难度不大,大部分时间都花在调试细节和踩坑上。
代码已经开源在 GitHub,用的 MIT 协议,任何人可以免费使用、修改、分发。
项目地址:https://github.com/wallechfox/countshare
GHCR 镜像:
https://github.com/wallechfox/countshare/pkgs/container/countshare
现在有了 AI 辅助,不懂代码也能做出能用的东西。
如果你也有类似的小需求,找不到合适的工具,不妨试试自己写一个。
作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~
