一、为什么要自建图床
写博客最离不开的就是贴图。一直用公共图床,心里总不踏实:有的贴广告,有的外链说失效就失效,还有的干脆跑路——文章还在,图全没了,比文章丢了还难受。
正好自己手里有 VPS,博客也跑在上面,干脆顺手搭一个自己的图床:图存在自己机器上,链接自己说了算,写到哪儿贴到哪儿。
要求还是老三样:只自己用、锁好门、做好备份。
二、选型先踩了一个大坑
图床最后选了兰空图床 Lsky Pro。但这里有个坑,我差点花了冤枉钱,先写出来给大家避雷:
兰空名下有两个名字几乎一样的产品——免费开源版 Lsky Pro,和付费版 Lsky Pro+(永久授权 299.99 元)。而官方文档站现在挂的是付费版的文档。我一开始照着文档站部署,一路装到安装向导弹出"许可协议 + 授权验证",才反应过来装错了版本:付款前赶紧停手,删干净,换回开源版的社区镜像重来。
经验就一条:开源软件动手之前,先去它的 GitHub 仓库确认版本和镜像,别只看文档站。
选开源版的理由也很实在:中文界面、Docker 一把梭、自带相册管理和外链复制,个人用完全够了。
三、部署:一个容器搞定
图床放在博客那台 VPS 上(配置够用,Docker、域名解析、每日备份都是现成的,不折腾新机器)。
老规矩,先看一眼机器现状,心里有数再动手:
docker ps && df -h / && free -h
硬盘还剩 80 多 G、内存宽裕,跑个图床绰绰有余。启动就一条命令:
docker run -d --name lsky-pro --restart=always -p 127.0.0.1:本机端口:8089 -e WEB_PORT=8089 -v /opt/lsky/data:/var/www/html 镜像名
三个关键点,和我之前搭导航页是一个套路:
-p 127.0.0.1:...:只监听本机,不直接对外暴露端口(Docker 映射端口是会绕过防火墙的,这点要特别注意);-v /opt/lsky/data:...:整站数据落盘在这个目录里,容器删了重建,图和账号都不丢;数据库在安装向导里选 SQLite:就我一个人用,一个文件就是整个数据库,以后备份时把数据目录整个打包就行,简单粗暴。
容器起来后先在本机验活,返回 200 再往下走:
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:<本机端口>
对外访问我走的是 Cloudflare Tunnel:在原有隧道里加一条规则,图床子域名指向本机的服务端口,HTTPS 证书这些隧道全包了,服务器防火墙依然只开 SSH 一个口。
装好之后打开站点,安装向导就两步:环境检测、填管理员邮箱和密码。密码记得存进密码管理器,丢了可没地方找回。
四、上线先锁门
图床这种东西,一旦被人发现开放注册,就会变成别人的免费网盘,严重的还会被传违规图片连累服务器。所以正式用之前,先把门锁死:
关闭注册:只留自己一个账号;
关闭游客上传;
关闭公开画廊:别人打开站点只能看到登录页,看不到我有哪些图;
文件名保持随机生成:就算有人猜链接,也枚举不出来。
验收方法很土但有效:开一个浏览器无痕窗口访问图床地址——只有登录框、没有任何注册入口,就算过关。
容量方面,系统默认给的额度很小,记得两处都要改:新用户的初始容量,和管理员自己的总容量(别问我怎么知道的,仪表盘上数字没变就是没改对)。单个文件大小上限也按需放大,我设了 20 MB,手机照片和截图都够了。
五、这篇最重要的一段:照片里的定位
这趟折腾最大的收获,不是图床本身,是一个认知纠正。
手机照片的 EXIF 信息里带着 GPS 定位,精确到你拍照的那条街。我原以为:图床里有个"图片转换格式"的选项,转成 WEBP 之后,定位信息应该会在转码时被洗掉吧?
实测结论:不会。 我做了两轮实验:
手机浏览器直传一张相册原图(不要用微信中转,微信会把 EXIF 吃掉,实验就不准了);传完先在服务器上把存档文件找出来对上号:
find /opt/lsky/data/storage -type f | grep -i "jpg\|webp"
然后把这张存档文件下载回电脑,右键属性看详细信息——经纬度完整保留; 2. 把图床设置改成"上传后转 WEBP",重传同一张图,文件确实变成了 .webp,再下载检查——定位还在,数值一模一样。
也就是说,兰空的转格式只是换了个包装,照片里的元信息原样搬家。
中间还有个小插曲:我本来想直接在服务器上用一条命令查 EXIF,兴冲冲地跑了 docker exec 进容器调 PHP 的 exif_read_data 函数,结果报错说函数不存在——容器里那个命令行 PHP 压根没装 exif 扩展。工具查了半天,最后发现最靠谱的验法还是最土的那个:下载回自己电脑,右键看属性。其他图床是不是也这样我没测过,但这个实验提醒了我:任何"以为会被处理掉"的隐私,都要自己验一遍才算数。
最后我的处置很简单,立一条使用纪律:图床只放准备公开发布的图(博客配图、论坛贴图、截图);带定位的手机生活原图,一律不进图床;证件、孩子这类私密照片更不用说,放自己的私有网盘。技术上当然也有办法(写个脚本定时给新图摘掉 GPS 段),但对我来说,纪律比脚本可靠,也省得维护——先这样用着。
六、备份:多写两行就行
博客机本来就有一份每日备份脚本:每天凌晨自动把博客数据和数据库打包,滚动保留 7 天。图床的数据目录是现成的,只要给脚本加两行:一行把图床目录打包成带日期的压缩包,一行按同样的规矩清理过期包(脚本里的 $B 是备份目录、$D 是当天日期,博客数据那份打包也是同一个套路):
tar -czf $B/lsky-data-$D.tar.gz -C /opt lsky 2>/dev/null
find $B -name 'lsky-*' -mtime +7 -delete
改完先手动跑一次脚本(bash 脚本路径),再打开新生成的备份包验货:
tar -tzf 备份包文件.tar.gz | grep -E "database.sqlite|uploads" | head
能列出数据库文件和图片目录,才算真备上了。备份这事,"脚本没报错"不等于"数据在包里",必须开包看一眼。
七、PicGo:让贴图变成顺手的事
图床网页上传其实已经够用,但写博客时最舒服的姿势是 PicGo:截图之后一键上传,Markdown 链接自动复制好,去文章里粘贴就行。
配置过程有两个小插曲,顺手记一下:
PicGo 的插件市场里搜兰空,能出来好几个同名插件。认准为开源版做的那个(介绍里会写明),别装成付费版的;
插件安装失败、失败码 1,多半是电脑上没有 Node.js——PicGo 装插件要调用它自带的 npm。去 nodejs.org 装个 LTS 版,再回 PicGo 重装插件就好了;
插件只需要填两样:图床的域名,和一枚 Token(令牌)。Token 是在自己电脑上用管理员邮箱和密码向图床接口"换"出来的,只存在 PicGo 本地,不要发给任何人,它就相当于图床的钥匙。换到之后粘贴进去,设为默认图床,完事。
换 Token 的通用命令长这样(域名和账号换成自己的):
curl -X POST "https://你的图床域名/api/v1/tokens" -F "email=你的邮箱" -F "password=你的密码"
返回的 JSON 里 token 字段就是令牌。提醒一句:别把这种带密码的命令存进脚本文件或者笔记里,换完就让它留在当次会话里。
验收也简单:随便截个图,在 PicGo 里点剪贴板上传,把得到的链接贴到论坛发帖框里——图能正常显示,全线打通。
八、小结
这一趟下来,自用图床算是立住了,回头看靠的就是三件事:
锁门:关注册、关游客、关画廊,只自己用;
备份:图和数据库每天自动打包,并且真的开包验过;
管住定位:图床只放公开图,带 GPS 的原图不上传——这条是实测换来的,比什么都值。
软件版本不用追新,稳定跑着就行。折腾的乐趣在于过程,但落点一定得是"以后写文章更省事",不然就是给自己找活干了。
评论