Docker 中安装 MinIO 作为静态资源服务

https://min.io/

本文主要记录在 Ubuntu 24.04 x64 上使用 Docker 安装 MinIO 作为静态资源服务的流程。基于 MinIO,可以满足图床、静态存储、对象存储等应用场景。

docker-compose 安装 MinIO

本文使用的 Docker 版本为:Docker version 27.3.1, build ce12230

docker-compose.yml 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 高版本的 docker-compose 会自动配置 version, 此处为空

services:
minio:
image: minio/minio
ports:
- 51080:9000 # api 端口
- 51180:9001 # 控制台端口
environment:
MINIO_ROOT_USER: root # 管理后台用户名
MINIO_ROOT_PASSWORD: root_password # 管理后台密码,最小8个字符
volumes:
- ./data/data:/data # 映射当前目录下的data目录至容器内/data目录
- ./data/config:/root/.minio/ # 映射配置目录
command: server --console-address ':9001' /data # 指定容器中的目录 /data
restart: always
networks:
- nginx_network

networks:
nginx_network:
external: true

将上述内容保存为 docker-compose.yml 文件,然后在目录中执行 docker compose up -d 运行实例。

配置 nginx

一台服务器可能有多个服务,因此将 nginx 独立成一个单独的 docker-compose,其它容器通过 nginx_network 与 nginx 容器相连。

nginx 的 docker-compose.yml 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
services:
nginx:
restart: always
container_name: nginx
image: nginx
ports:
- 80:80
- 443:443
volumes:
- ./data/cert:/etc/nginx/cert
- ./data/conf.d:/etc/nginx/conf.d # 每个服务的 nginx 配置单独成一个 `*.conf` 文件放到 conf.d 目录中,nginx 会自动加载
environment:
- NGINX_PORT=80
- TZ=Asia/Shanghai
# privileged: true
networks:
- nginx_network

networks:
nginx_network:
external: true

minio 的 nginx 配置为(文件路径 xxx/data/conf.d/minio.conf):

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
upstream minio_upstream {
# minio 为主机名,在 docker-compose 中定义的,端口为 docker 中 MinIO 的端口
server minio:9000;
}

server {
# 域名与端口
server_name obs.uamazing.cn;
listen 443 ssl;

# ssl
ssl_certificate /etc/nginx/cert/uamazing.cn_ecc/uamazing.cn.cer;
ssl_certificate_key /etc/nginx/cert/uamazing.cn_ecc/uamazing.cn.key;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:!MD5;
# 强制 https
add_header Strict-Transport-Security "max-age=31536000";
# 其它 ssl 优化
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:2m;
ssl_session_timeout 1h;
ssl_session_tickets off;

# 不限制文件大小
client_max_body_size 0;
# 禁用了代理缓冲, 提升速度
proxy_buffering off;

access_log /var/log/nginx/proxy_access.log main;
error_log /var/log/nginx/proxy_error.log info;

location / {
# 设置多个 HTTP 头部来传递客户端的真实 IP 地址、请求的原始协议和主机名等信息
# 这些头部对于后端服务器处理请求、记录日志和进行安全审计非常重要
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 Host $http_host;
proxy_set_header X-NginX-Proxy true;

proxy_connect_timeout 3600;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
chunked_transfer_encoding off;

proxy_pass http://minio_upstream;
}
}

MinIO 创建静态

为了实现图床功能,可以在 MinIO 中创建一个 public 仓库来实现。

具体步骤如下:

  1. 使用管理端口登陆 MinIO

  2. 创建 Bucket

    通过【Buckets/Create Bucket +】来创建一个新的存储桶,输入存储桶的名称,示例中为 public,最终结果如下图所示:

    image-20240927171130390.png
  3. 修改 public Bucket 的访问策略

    单击【Access Policy】后面的铅笔图标,将其从【Priave】修改为【Public】,单击应用【Set】应用

    image-20240927171643219

    由于 Public 策略允许查看 Bucket 某个目录下的文件列表,因此要对该权限进行禁用。将访问策略从【Public】改成【Custom】,然后移除 Statement.Action 中的 s3:ListBuckets3:ListBucketMultipartUploads,最终结果如下:

    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
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Principal": {
    "AWS": [
    "*"
    ]
    },
    "Action": [
    "s3:GetBucketLocation"
    ],
    "Resource": [
    "arn:aws:s3:::public"
    ]
    },
    {
    "Effect": "Allow",
    "Principal": {
    "AWS": [
    "*"
    ]
    },
    "Action": [
    "s3:AbortMultipartUpload",
    "s3:DeleteObject",
    "s3:GetObject",
    "s3:ListMultipartUploadParts",
    "s3:PutObject"
    ],
    "Resource": [
    "arn:aws:s3:::public/*"
    ]
    }
    ]
    }

    单击【Set】进行应用。

增加读写用户

若要在程序中向 public 桶中上传文件,需要创建一个具有读写 public 目录权限的 Access Key。

打开 Restict beyond user policy,修改为下列权限策略:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::public",
"arn:aws:s3:::public/*"
]
}
]
}

最终结果如下图所示:

image-20240927180156357

添加完成后,即可在程序中使用该 Access Key 和 Secrect Key 进行上传操作。