Nginx图床
Minio + Nginx
MinIO
MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口, 非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等, 而一个对象文件可以是任意大小,从几kb到最大5T不等。
Docker 命令:
docker run -itd -p 9000:9000 --name minio \ -v ~/docker/minio/data:/data -v ~/docker/minio/config:/root/.minio \ -e "MINIO_ACCESS_KEY=你的账号" -e "MINIO_SECRET_KEY=你的密码" \ minio/minio server /data
-
把里面
data
和config
文件夹改成你想要存储数据和配置文件的文件夹,然后把账号密码填进去就行了。 -
如果想用
docker-compose
或者 k8s 启动,请参考官方文档,挺详细的而且竟然还有中文版。 - 启动之后,打开 9000 端口之后就可以看到自带的管理界面了。
Minio 的存储逻辑很简单,分成多个 bucket(桶),没个桶内部就是以文件夹为层级,
而且所有文件是直接存储在文件系统上的,没有分成小文件块之类的,因此你可以直接复制到你的
data
文件夹内。
但是,你没办法直接用链接访问放在 Minio 中的文件,虽然它提供了分享等功能,
但是提供的是一个下载链接,我们需要的是类似于图片预览,因此需要一个Nginx
作为文件服务器。
Nginx
Nginx 就不用赘述了,我也是用 Docker 启动的,命令如下:
docker run -itd --name image -p 8081:80 \ -v ~/docker/image/conf:/etc/nginx/conf.d \ -v ~/docker/minio/data:/data nginx
可以看到,我把 Minio 的数据文件夹挂载进去了,挂载到了 Nginx 容器的/data
目录。然后修改Nginx
配置文件如下:
server { listen 80; server_name localhost; charset koi8-r; access_log /var/log/nginx/host.access.log main; location ^~ /blog/ { root /data/; } }
这里,我是在 Minio 中创建了一个桶,名字叫blog
,它其实对应着 Minio 存储目录中的blog
文件夹。
配置完 Nginx 之后,其实我如果想查看 Minio 中blog
桶中的/testpath/test.png
,只需要访问:
http://localhost:8081/blog/testpath/test.png
就可以了。
于是只要我向 blog 这个桶中上传文件,文件就可以直接通过 Nginx 预览了。
Typora 和 Python 脚本
Typora用来写markdown时,配合官方的脚本就可以自动把文档中用到的图片传到服务器上去。
现在只需要准备一个脚本,让 Typora 能够向 Minio 上传文件就行了。选择 Python 是因为 Minio 官方提供了 API,而且我正好熟悉。
Typora 上传的规则是这样,它会让你填写你的命令,比如你填写python upload.py
,
它就会执行python upload.py "image1-path" "image2-path"
等等把图片位置作为参数穿进去。
然后约定好需要你传回来上传完毕后的每张图片位置,每张图片占一行。
比如上面的例子,传了两张,它就会自动从后往前查两行,作为 URL 替换掉原本的图片链接。
于是我写了个脚本如下,写的比较糙,可以作为参考:
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)
我是把博客图片都放到了 blog 这个桶,然后按照月份创建文件夹,每个月的都放在同一个文件夹, 文件名是用的 uuid。具体的逻辑想要修改的话自己改上面的脚本吧。
搞定之后在 Typora 里面填上脚本,然后点击测试,就可以看看结果了,测试通过就万事大吉了,写个博客插入图片看看吧!