你也许不需要图床

背景

使用hexo写博客已经有三四年了。
最困扰的问题依然是上传需要插入的contents的问题。

上传图片方式演化

由于hexo只是个静态博客生成器,
并不像wordpress那样有强大的contents管理功能,所有的contents我们只能通过上传到某个地方然后引用。
很显然,第一个被pass的解决方案是把图传到公共的图床上去。比如新浪微博或者七牛云存储。
前者类似盗链行为,后者复杂的流量收费计算方式实在是让人头疼。

我们的目标是,把所有的图片都放置在自己拥有管理权的地方。

自己host的图床工具

这是最早使用的解决方案。首先在github上找了个docker封装好的图床web app。然后挂到服务器上。
总体来说没什么大问题。每30分钟我都会备份一下docker container里面的图片。

1
30 * * * * /usr/bin/docker cp b7ceed2898de003e02b0addee90d0d50c63d046cd422d17dc5ba9085d44ea237:/usr/share/nginx/html/upload /data/pictshareuploads/upload/

但是后来服务器运营商MAINT停机的时候,我的docker就挂了。之前的图片虽然有作备份,现存的图姑且是全部救了回来,就是container重启之后不知道为啥UI什么的全部发生了变化,我也再也没有权限上传图片了。

当然花时间理清楚思路固然重要,不过对于我只想要简简单单解决上传图片的目的来说,显然有些多余了。

于是我把眼光转向了吱呀呀转动着的挂在自己家的NAS。

自宅NAS的复杂繁琐

QNAP这个NAS服务器真的是非常良心。不但免费提供了DDNS绑定,各种定制的contents管理工具也是十分便捷。
唯一让人头疼的是,当我们要上传图片并获取公链的时候,步骤太过于复杂。

  1. 打开FileStation, 然后选择上传。

  1. 选择上传的文件之后,点击共享,然后勾选永久共享。

  1. 获取共享链接之后,在共享链接的界面点开图片,获取真正的链接。然后复制到剪贴板。

更要命的是由于手动步骤太多导致很多时候直接就是贴错了图。

痛定思痛,我决定花点时间来解决传图的问题。目标是使用最短的时间上传任意大小的图片,并且减少操作的失误。

NGINX + SCP

这个方法的思路是。

  1. 获取本地图片/视频的md5。

  2. 用scp将本地图片上传到自己服务器的公开目录上,并重命名成”md5+extension”的名称。

  3. 拼接出图片的url,自动复制到剪贴板。

事先准备nginx的公开目录。

我们建立一个alias,把新建的目录挂到wwww.bocchi.tokyo/upload的path下面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
listen 443 http2;

ssl on;
server_name www.bocchi.tokyo;
ssl_certificate /etc/letsencrypt/live/www.bocchi.tokyo/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.bocchi.tokyo/privkey.pem;
root /var/www/myblog;
index index.html;

location / {
add_header Cache-Control max-age=0;
add_header Cache-Control no-store;
add_header Pragma no-cache;
#rewrite ^ https://$http_host$request_uri? redirect;
try_files $uri $uri/ =404;
}
location /upload/ {
alias /var/www/html/upload/;
}
}

本地写一个bash脚本,当执行hl my_image.jpg的时候,会把图片自动上传到公开目录并将合成的url复制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash


md5=`md5 -q "$1"`
filename=$(basename -- "$1")
extension="${filename##*.}"

hashedName="$md5.$extension"

echo "file name is : $hashedName"

# cp $1 /tmp/$hashedName

scp "$1" gyorou@bocchi.tokyo:/var/www/html/upload/$hashedName

if [ $? -eq 0 ]; then
echo "https://www.bocchi.tokyo/upload/$hashedName" | pbcopy
echo "copied https://www.bocchi.tokyo/upload/$hashedName to clipboard"
else
echo FAIL
fi

当然为了在上传过程中不提示输入密码,ssh的无密码登陆也需要设置好。不过这个就略去不谈了。

试一下效果。

后记

看了一下现在服务器的容量,大概暂时是没有什么问题。
接下来可能会考虑把博客和邮箱完全扔到NAS上,彻底省去服务器的这笔开销吧。