图床搭建|minio详细使用教程|避坑指南

2023年 7月 31日 45.3k 0

原文链接: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:::user/"
                 ]
             },
             "Action": [
                 "s3:GetObject",
                 "s3:PutObject"
             ],
             "Resource": [
                 "arn:aws:s3:::/*"
             ]
         }
     ]
 }
  • 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=
      - MINIO_ROOT_PASSWORD=
    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中的资源,链接为:http://[服务器ip地址]:[minio的api端口号,默认9000]/[bucket-name]/[file-name]

  • Nginx反向代理

    Web管理页面

    server {
        listen 80;
        listen 443 ssl http2;
        server_name ;
    
        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 ;
    
        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
    如果用admin的身份登录web管理界面并创建access key,那么这个access key具有很高的权限,比如
    - 列出所有存储桶和对象;
    - 创建、删除、修改存储桶;
    - 上传、下载、删除、复制、移动对象;
    - 获取对象元数据和ACL(访问控制列表)
    

    为了安全起见,你可以先创建一个user,有两种方法创建user

    • 方法一: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 /
    比如
    mc mirror --overwrite minio/article article
  • 把本地的bucket备份到服务器,使用--overwrite覆盖不一样的内容
    mc mirror --overwrite /
    比如
    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='',
                   secret_key='',
                   secure=False)
                   
    def copy_src_to_dest(src,dest):
        try:
            result = client.list_objects('', 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连接
    • srcdest 相对路径。如果有个文件夹的绝对路径是///,那么只需要写/就行了

    更多文章在我的博客:wmwm.me

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论