原文链接:wmwm.me/article/456…
免费的图床服务,不靠谱,免费的总是最贵的,并且免费的将来一定会遇到很多麻烦
付费的图床服务,域名要存案,并且自己的资源很有可能会被服务商看个精光
所以只能自建图床了,自建图床有很多方案,我选择了最朴实的minio,一个开源的目标存储服务。 之前也折腾过nextcloud,seafile等开源网盘,可是网盘终究是网盘,和minio还是有一定的差距,就凭”权限拜访”这个功用,就现已秒杀了网盘。当然网盘也有相应的优势,可是要搭建图床的话,网盘不是首选
为什么选择minio
minio的存储方式采用了S3
S3(Simple Storage Service)是由亚马逊公司开发的一种目标存储服务,由于S3服务的广泛运用和影响力,S3 API现已成为云存储领域的事实标准之一。 S3 API是一种RESTful API,能够用于办理目标存储服务中的数据,包含上传、下载、删去、列出目标等操作。S3 API的首要特点是简单易用、可扩展、高度兼容,因而被广泛应用于各种目标存储服务中。 除了亚马逊公司自己的S3服务之外,许多其他云存储服务供给商也支撑S3 API,例如微软的Azure Blob存储、Google Cloud的Cloud Storage等,这些服务都兼容S3 API,使得开发者能够运用相同的API来拜访不同的云存储服务。
s3运用IAM(AWS Identity and Access Management)来办理权限:哪些用户可拜访哪些AWS资源
权限操控 Access Policy
- 能够用来设置bucket的权限
- 能够用来设置user的权限
格式
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "statement-example",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::<account-id>:user/<username>"
]
},
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::<bucket-name>/*"
]
}
]
}
-
Version
“2012-10-17” 指定了战略语法版别号,表明该战略是基于2012年10月17日版别的语法编写的。 -
Statement
[] 是一个数组,包含了一个或多个拜访操控规矩(Statement)。 -
Sid
Statement id,能够随便写,首要是给当前的statement添加一个注释信息 -
Effect
“Allow” 表明该规矩答应拜访操控。”Denied”表明回绝拜访 -
Principal
指定答应或回绝拜访资源的主体。在这个拜访战略中,account-id是AWS账户ID,username是要限制拜访的access key的用户名 -
Action
表明答应拜访者履行的操作 -
Resource
答应拜访的资源
Amazon供给了一个自动生成policy的网站awspolicygen.s3.amazonaws.com/policygen.h…
运转minio容器
以docker-compose方式运转在单独的minio_default网络中,其他容器加入网络后运用”minio”可直接拜访s3服务
services:
minio:
container_name: minio
image: quay.io/minio/minio
restart: always
volumes:
- $PWD/data:/data
environment:
- TZ=Asia/Shanghai
- MINIO_ROOT_USER=<root用户>
- MINIO_ROOT_PASSWORD=<root暗码>
ports:
- "9001:9000"
- "9091:9090"
command: server /data --console-address ":9090"
-
9000
api恳求端口 -
9090
Web办理页面 -
MINIO_ROOT_USER
MINIO_ROOT_USER
Web页面登录时的用户名和暗码 -
-e TZ=Asia/Shanghai
设置中国时区 -
/data
这个文件夹里有minio的装备文件和上传到服务器上的资源(图片、视频…),这个文件千万不能删去,删掉后你的文件就没了
其他内容保持不变,直接运转docker compose up -d
就能够,然后拜访http://[服务器ip地址]:9090就能够看到登录界面
装备匿名拜访
- 在web界面创立一个bucket,bucket能够了解成”文件夹”
- 设置bucket的policy为custom,答应一切人(包含匿名用户)能够读取内容,否则html的img标签就无法加载出图片
{ "Version": "2012-10-17", "Statement": [ { "Sid": "allow-anybody-read", "Effect": "Allow", "Principal": { "AWS": [ "*" ] }, "Action": [ "s3:GetObject" ], "Resource": [ "arn:aws:s3:::<bucket-name>/*" ] } ] }
装备好以后,用你的浏览器试着拜访一下bucket中的资源,链接为:http://[服务器ip地址]:[minio的api端口号,默许9000]/[bucket-name]/[file-name]
Nginx反向署理
Web办理页面
server {
listen 80;
listen 443 ssl http2;
server_name <二级域名,比如admin.example.com>;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privatekey.pem;
# Allow special characters in headers
ignore_invalid_headers off;
# Allow any size file to be uploaded.
# Set to a value such as 1000m; to restrict file size to a specific value
client_max_body_size 0;
# Disable buffering
proxy_buffering off;
proxy_request_buffering off;
location / {
proxy_pass http://localhost:<端口号>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
# This is necessary to pass the correct IP to be hashed
real_ip_header X-Real-IP;
proxy_connect_timeout 300;
# To support websocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
chunked_transfer_encoding off;
}
}
api接口
server {
listen 80;
listen 443 ssl http2;
server_name <二级域名,api.example.com>;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privatekey.pem;
# Allow special characters in headers
ignore_invalid_headers off;
# Allow any size file to be uploaded.
# Set to a value such as 1000m; to restrict file size to a specific value
client_max_body_size 0;
# Disable buffering
proxy_buffering off;
proxy_request_buffering off;
location / {
proxy_pass http://localhost:<端口号>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 300;
# Default is HTTP/1, keepalive is only enabled in HTTP/1.1
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
}
}
数据备份
假如你的minio服务器通过了CDN署理,那么在数据备份的时候,一定要运用minio服务器的直接链接(也便是通过url能够直接拜访你的minio服务器,不通过cdn中转)这个问题查了我整整两天时间,现已有点崩溃了,是个大坑!!!
运用cdn署理的url进行数据备份,可能会由于cdn服务器的缓存问题,导致备份的数据不是最新的数据!!!
- 下载mc客户端,安装教程在这里
- 创立一个access key
为了安全起见,你能够先创立一个user,有两种方法创立user假如用admin的身份登录web办理界面并创立access key,那么这个access key具有很高的权限,比如 - 列出一切存储桶和目标; - 创立、删去、修正存储桶; - 上传、下载、删去、仿制、移动目标; - 获取目标元数据和ACL(拜访操控列表)
- 方法一:web办理页面能够直接创立
- 方法二:通过mc客户端创立,ACCESSKEY和SECRETKEY也被用作登录账号和暗码
mc admin user add TARGET ACCESSKEY SECRETKEY
-
ACCESSKEY
Also called as username. -
SECRETKEY
Also called as password.新创立的user没有任何权限,咱们需求给他分配一些权限,比如:readonly/writeonly/readwrite,只有分配了权限,user才能够拜访资源。在这里咱们能够给他分配readwrite权限,由于要备份数据
-
- 然后为方才的access key添加一个别名
mc alias set
例如:
mc alias set minio example.com
或者直接编辑装备文件,macos的装备文件在
~/.mc/config.json
- 把服务器上的bucket备份到本地,运用
--overwrite
掩盖不一样的内容 mc mirror –overwrite / <path/to/local/dir> 比如 mc mirror –overwrite minio/article article - 把本地的bucket备份到服务器,运用
--overwrite
掩盖不一样的内容 mc mirror –overwrite / <path/to/local/dir> 比如 mc mirror –overwrite minio/article article
避坑
- 拜访图片资源时,要运用api的端口号,不能是webUI端口号
- 测试阶段,假如出现奇奇怪怪的问题,就看下你的恳求url有没有通过cdn署理
补充
- minio默许运用
ETag
进行缓存。能够在cdn服务器上设置cache-control:max-age - minio默许答应跨域拜访。假如要设置CORS,能够在cdn服务器上设置
- minio默许不开启gzip紧缩。不建议minio服务器开启gzip紧缩,会影响原始文件大小,假如要开启紧缩,能够让cdn服务器进行紧缩
minio sdk
官方供给的mc客户端有时候并不能满意我的要求,只能运用api自己完结想要的功用,我选择python sdk
python sdk官方文档链接:min.io/docs/minio/…
安装:pip install minio
功用1-文件夹的重命名/文件夹拷贝
from minio import Minio
from minio.commonconfig import CopySource
client = Minio(endpoint='<服务器的地址:端口>',
access_key='<自己的access_key>',
secret_key='<自己的secret_key>',
secure=False)
def copy_src_to_dest(src,dest):
try:
result = client.list_objects('<bucket名称>', recursive=True,prefix=src)
for obj in result:
print(f'正在将{obj.object_name}仿制到{obj.object_name.replace(src,dest)}')
client.copy_object('blog', obj.object_name.replace(src,dest), CopySource("blog", obj.object_name))
print('仿制完结')
except OSError as err:
print(err)
-
secure=False
表明运用http连接 -
src
和dest
相对路径。假如有个文件夹的绝对路径是/<bucket-name>/<article-name>/<year>
,那么只需求写<article-name>/<year>
就行了