Vuhks

壁立千仞,无欲则刚

自建图床

自建私有图床

参考知乎Minio+Nginx搭建私有图床,写博客从未这么爽 - 知乎 (zhihu.com)

背景

1.使用hexo写东西的时候难免要上传一些图片,hexo又是使用markdown文件来生成网页的,所以一般用typora来编写。

2.Typora自带一个功能,可以自动将图片上传。其支持picgo、自定义命令等。

image-20230609170847116

1.搭建图床

这里是参考知乎Minio+Nginx搭建私有图床,写博客从未这么爽 来完成的。

我是直接搭建在自己的黑群晖上(内网穿透等可以再写一篇记录一下),以下是具体实现步骤。

1.1 MinIO docker搭建

1.1.1 搭建服务端

参考MinIOMinIO对象存储 — MinIO Object Storage for Container搭建

1
2
3
4
5
6
7
8
9
10
mkdir -p ${HOME}/minio/data
docker run \
-p 9000:9000 \
-p 9090:9090 \
--user $(id -u):$(id -g) \
--name minio1 \
-e "MINIO_ROOT_USER=ROOTUSER" \
-e "MINIO_ROOT_PASSWORD=CHANGEME123" \
-v ${HOME}/minio/data:/data \
quay.io/minio/minio server /data --console-address ":9090"

报错

1
docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/create?name=minio1": dial unix /var/run/docker.sock: connect: permission denied.

解决:权限不足,当前用户不能建立sock,用root用户或者sudo命令进行。

中间解决了一个问题,提示证书过期

img

具体解决:

网上找了很多教程,比如修改daemo.json文件,因为是dsm系统,这个文件可能没有生效;修改dsm的注册表为阿里云的镜像加速源,也没有生效。

最后在dsm的docker界面搜索的minio这个镜像直接下载后,运行的下面的docker命令。

我的docker只懂一点皮毛,有时间需要深入的学习一下

1
2
3
4
5
6
7
8
9
sudo docker run -itd \
-p 9000:9000 \
-p 9090:9090 \
--name minio \
-v ~/docker/minio/data:/data \
-v ~/docker/minio/config:/root/.minio \
-e "MINIO_ROOT_USER=*****" \
-e "MINIO_ROOT_PASSWORD=*****" \
quay.io/minio/minio server /data --console-address ":9090"

在地址栏中输入对应ip:9090即可进入网页控制端,能显示这个页面就代表已经成功了。

image-20230609220856117

1.1.2 搭建本地图床

参考这个MinIO搭建本地图床 - 一一风和橘 - 博客园 (cnblogs.com)

  • 新建bucker桶

image-20230609224209442

  • 修改Access Rule

image-20230609224152132

1.2 Nginx docker搭建

1
2
3
4
5
6
7
docker run -itd  \
--name image \
-p 8081:80 \
-p 8083:443 \
-v ~/docker/image/conf:/etc/nginx/conf.d \
-v ~/docker/minio/data:/data nginx

在conf文件夹下创建一个minio.conf(命名无所谓 ),添加以下配置

1
2
3
4
5
6
7
8
9
server {
listen 80;
server_name localhost;
charset koi8-r;
access_log /var/log/nginx/host.access.log main;
location ^~ /blog/ {
root /data/;
}
}

现在就可以使用 http://192.168.6.202:8081/blog/123.jpg 这个地址来直接访问图片。

– 其中 blog是minio的bucket名,需要与配置文件中的location路径一致

– 8081是nginx代理

注:长期使用的话需要用compose来管理容器。

Docker Compose | 菜鸟教程 (runoob.com)

2. 搭配Typora

直接偷文中的python脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import os
import time
import uuid
import sys
import requests
from minio import Minio
from minio.error import ResponseError
import warnings

warnings.filterwarnings('ignore')
images = sys.argv[1:]
minioClient = Minio("这里写你的Minio地址,格式为域名:端口,不带http://",
access_key='你的Minio账号', secret_key='你的Minio密码', secure=False)//secure为True的话第一项会填充为https://
result = "Upload Success:\n"
date = time.strftime("%Y%m", time.localtime())


def download(image_url):
local_path = os.getcwd() + "/temp"
r = requests.get(image_url, verify=False)
with open(local_path, "wb") as code:
code.write(r.content)
return local_path


for image in images:
if os.path.isfile(image):
file_type = os.path.splitext(image)[-1]
new_file_name = str(uuid.uuid1()).replace('-', '') + file_type
elif image.startswith("https://") or image.startswith("http://")://处理网络图片
if image.endswith(".png") or image.endswith(".jpg") or image.endswith(".jpeg") or image.endswith(".gif"):
url = image.split("/")
if len(url) > 1:
image = download(image)#先把网图下载到本地了,然后在传到Minio
new_file_name = url[-1]
else:
result = result + "error:parsing image error!"
continue
else:
result = result + "error:parsing image error!"
continue
else:
result = result + "error:parsing image error!"
continue
try:
minioClient.fput_object(bucket_name='blog', object_name=date + "/" + new_file_name, file_path=image)
if image.endswith("temp"):
os.remove(image)
result = result +"你的Nginx地址,比如http://yourdomain:8081" + "/blog/" + date + "/" + new_file_name + "\n"
except ResponseError as err:
result = result + "error:" + err.message + "\n"

print(result)

代码有问题。

2.1 使用picgo-core

2.1.1 安装

1
2
# 安装
npm install picgo -g

image-20230610102346066

1
#安装minio插件

具体插件参考Herbertzz/picgo-plugin-minio (github.com)

image-20230610102404196

2.1.2 配置

参考官方文档配置文件 | PicGo-Core

生成配置文件

1
picgo set uploader

image-20230610102738265

配置上传器

1
2
#
picgo use

image-20230610102900916

解决一个问题:这里是上传路径的问题

image-20230610103112784

解决一个问题:

1
[PicGo WARN]: S3Error: S3 API Requests must be made to API port.

image-20230610103221007

这个问题是minio设置的端口问题,应该为api的端口9000,而不是console的端口9090。

参考(30条消息) Minio上传图片时遇到的问题S3 API Requests must be made to API port._CoderPorter的博客-CSDN博客解决。

最后测试成功的页面

image-20230610103459198

2.2 typora 使用

刚开始用这个自带时出现未知错误,所以才用的pcigo的cli命令测试的。

image-20230610103557845

image-20230610103617898

后来也是上网查到,因为我们没有使用typora官方的下载,采用命令安装的,所以要采用自定义命令。参考Upload Images - Typora Support

image-20230610103904924

image-20230610104004931

最后采用这个成功

1
2
#
picgo u

image-20230610103641628

image-20230610104323821

2.3 内网穿透

现在暂时用的是ddns加内网穿透的方案,因为用的是openwrt做的端口转发,可能会不稳定,先暂时这样用吧

image-20230616164939096

image-20230616164905957

3.一些问题

3.1 net::ERR_SSL_PORTOCOL_ERROR

image-20230616170105987

原因:图片的url地址是http的头,但是博客的地址是https的头,需要一致。

解决:修改nginx代理即可,添加https证书。

3.1.1 申请SSL免费证书

途径:

1.Let’s Encrypt 比较复杂吧,可google

2.阿里云免费ssl 33种免费获取SSL证书的方式 - 知乎 (zhihu.com)

因为自己在阿里云购买的域名,所以直接使用阿里云免费ssl

步骤

  1. 登陆阿里云控制台,搜索ssl证书

  2. 点击免费证书,购买,再点击证书,即可活动一年免费证书

    image-20230622111805360

  3. 证书验证

阿里云控制台会自动给你添加记录,等待几分钟验证通过就行,状态为已签发。这里没有截图

  1. 证书下载

image-20230622112030790

3.1.2 docker 配置证书

1.上传上一步下载的证书

2.修改nginx配置文件

这里完全去掉了80的代理,也不再用代理访问了,直接用https访问。

   server {
                listen 443 ssl;
                server_name home.vuhks.top;
                ssl_certificate /etc/nginx/certs/1_home.vuhks.top.pem;
                ssl_certificate_key /etc/nginx/certs/1_home.vuhks.top.key;
                ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
                   ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
                ssl_prefer_server_ciphers on;
                client_max_body_size 50m;
                location ^~/blog {
                    proxy_pass http://192.168.6.202:9000;
                    proxy_set_header  Host  $host;
                    proxy_set_header  X-Real-IP  $remote_addr;
                    proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
                    }
            }

3.修改docker的启动命令,把证书的路径加上去

1
2
3
4
5
6
7
docker run -itd  \
--name image \
-p 8081:80 \
-p 8083:443 \
-v ~/docker/image/conf:/etc/nginx/conf.d \
-v ~/docker/image/certs:/etc/nginx/certs \
-v ~/docker/minio/data:/data nginx

image-20230622153525132

这是因为命令输错了,docker run中的可执行指令有错误。

image-20230622150949142

这是因为编译安装的时候没有启动没有添加ssl模块

好像不是因为这个,我把报错的配置删掉就好了。

1
2
 *62 no live upstreams while connecting to upstream, client: 172.17.0.1, server: home.vuhks.top, request: "GET /favicon.ico HTTP/1.1", upstream: "http://localhost/favicon.ico", host: "home.vuhks.top:8083", referrer: "https://home.vuhks.top:8083/blog/1234.jpg"
172.17.0.1 - - [22/Jun/2023:08:35:14 +0000] "GET /favicon.ico HTTP/1.1" 502 559 "https://home.vuhks.top:8083/blog/1234.jpg" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.51" "-"

image-20230622163602145

1
2
3
4
5
6
7
8
location /xxx/ {
proxy_pass http://localhost:9000/;
# 下面这三个记得加上
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

这样改写之后仍然不行,继续google,最后发现日志里的upstrem里“http://127.0.0.1:9000/blog/1234.jpg”这里有问题,因为我直接访问192.168.6.202:9000/blog/1234/jpg是可以访问的。所以猜错是docker的原因,不能这么写配置文件?

所以我直接将其改为192.168.6.202:9000

3.1.3 修改picgo配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"picBed": {
"uploader": "minio",
"current": "minio",
"minio": {
"endPoint": "home.vuhks.top",
"port": "9000",
"useSSL": false,
"accessKey": "vuhks",
"secretKey": "zxcv7890",
"bucket": "blog",
"sameNameFileProcessingMode": "覆盖",
"baseDir": "/",
"customDomain": "home.vuhks.top:9000",
"isAutoArchive": true
},
"transformer": "path"
},
"picgoPlugins": {
"picgo-plugin-minio": true
}
}