前言

MinIO是什么?

MinIO is an object storage solution that provides an Amazon Web Services S3-compatible API and supports all core S3 features. MinIO is built to deploy anywhere - public or private cloud, baremetal infrastructure, orchestrated environments, and edge infrastructure.

翻译过来就是说:MinIO 是一个对象存储解决方案,提供与 Amazon Web Services S3 兼容的 API,并支持所有核心 S3 功能。MinIO 可部署在任何地方——公有云或私有云、裸机基础设施、编排环境以及边缘基础设施。

有什么用?

这就得看你需求,我刚好专门买了一台大硬盘服务器拿来搞存储节点,顺手就自建一个,话不多说教程开始

服务器配置要求?

没啥大的要求我存储服务器也才1C2G,咱存储节点就不要上啥面板啥的了,内存本来就不大,docker啥的我都不建议使用

正文开始

准备工作

  • 一台服务器装好系统,本次以Debian12为例

  • SSH软件(本教程采用Termius)

  • 聪明的脑袋瓜,勤劳的双手

更新系统的软件包列表和已安装的软件包

sudo apt update && sudo apt upgrade -y

jdavzadlam.png

下载软件包

wget https://dl.min.io/server/minio/release/linux-amd64/minio_20250422221226.0.0_amd64.deb
ls

akxitahjmi.png

安装软件包

sudo dpkg -i minio_20250422221226.0.0_amd64.deb

issyeymsip.png

创建用户和组

创建 minio-user 用户和组: 使用以下命令创建一个专门用于运行 MinIO 服务的系统用户(没有家目录,不能用于登录):

sudo adduser --system --no-create-home --group minio-user
  • --system: 创建一个系统用户。

  • --no-create-home: 不需要为这个服务用户创建家目录。

  • --group: 同时创建一个与用户名同名的组 (minio-user),并将用户添加到该组。

klwfypzjzr.png

创建数据存储目录并设置权限

MinIO 需要一个专用的目录来存储对象数据。创建一个目录,并确保运行 MinIO 服务的用户对此目录有读写权限。

sudo mkdir -p /data/minio 
sudo chown minio-user:minio-user /data/minio

当然了此处我的路径是/data/minio,你们可以视情况调整

配置 MinIO Systemd 服务环境变量

MinIO 的 Systemd 服务通常通过 /etc/default/minio 文件读取配置。你需要编辑这个文件来设置 MinIO 的 Root 用户、密码和数据存储路径等。我们将配置 MinIO 控制端监听在9000 端口,API端我们监听在9001端口。我推荐大家采用Nginx反代来配置域名,不建议使用IP+端口的形式

sudo nano /etc/default/minio

为什么是这个文件?

有人肯定有这个疑问,没事,我们来看MinIO Systemd 配置文件里面的内容

sudo systemctl cat minio.service

可以看见里面内容,我已经对所有内容进行全部解读

# /lib/systemd/system/minio.service

[Unit]
# 为服务提供人类可读的描述,显示在 systemctl status 等命令中。
Description=MinIO
# 指定 MinIO 官方文档的 URL。
Documentation=https://docs.min.io
# 表示一个弱依赖关系 (weak requirement)。服务希望网络在线 (network-online.target),
# systemd 会尝试与此服务一同启动 network-online.target。
# 但是,如果 network-online.target 启动失败,minio.service 仍会尝试启动。
Wants=network-online.target
# 指定启动顺序依赖。此服务仅在 network-online.target 成功激活后才会启动,确保网络连接已建立。
After=network-online.target
# 在启动服务前,systemd 会验证指定的文件 (/usr/local/bin/minio) 是否存在且具有执行权限。
# 如果条件不满足,服务启动将失败。
AssertFileIsExecutable=/usr/local/bin/minio

[Service]
# 指定服务的启动类型。'notify' 表示服务守护进程在完成启动后会通过 sd_notify 向 systemd 发送通知消息。
# 这让 systemd 可以精确跟踪服务何时真正准备就绪。
Type=notify

# 设置执行进程(MinIO 服务器)的工作目录。
WorkingDirectory=/usr/local

# 指定运行 MinIO 进程的系统用户账户。以专用的非 root 用户运行可以增强安全性。
User=minio-user
# 指定运行 MinIO 进程的系统用户组账户。
Group=minio-user
# 一项安全特性(需要较新内核/systemd)。设置为 'invisible' 时,
# 该服务的进程对同一用户运行的其他进程是隐藏的,防止意外的信号发送或进程窥探。
ProtectProc=invisible

# 从指定文件 (/etc/default/minio) 加载环境变量。
# 这些变量(如 $MINIO_OPTS, $MINIO_VOLUMES)可以在 ExecStart 命令中使用。
# 前缀 '-' 表示如果此文件丢失,服务启动*不会*失败。
EnvironmentFile=-/etc/default/minio
# 定义用于启动 MinIO 服务器进程的实际命令和参数。
# 它使用了从 EnvironmentFile 加载的变量。
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES

# 配置服务自动重启策略。'always' 表示如果 MinIO 进程因任何原因退出
# (如崩溃、收到信号、非 0 退出码的正常退出),systemd 都会自动尝试重启它,
# 除非是被 `systemctl stop` 命令明确停止的。
Restart=always

# 设置 MinIO 进程可以拥有的最大打开文件描述符(文件、套接字)数量的资源限制。
# 1048576 是一个高数值,通常是高并发服务器所需要的。
LimitNOFILE=1048576

# 禁用 systemd 基于 cgroup 的内存计费功能。
# 注释表明这样做可能是因为它存在缺陷或会干扰 MinIO 的性能。
MemoryAccounting=no

# 设置服务 cgroup 内可以创建的最大任务(线程/进程)数量。
# 'infinity' 表示 systemd 不施加限制(但内核本身的限制仍然适用)。
TasksMax=infinity

# 禁用服务启动、停止或重启操作的超时限制。
# systemd 将无限期等待服务发出就绪信号 ('notify') 或完成停止过程。
# 对于可能需要很长时间进行初始设置或优雅关闭的服务很有用。
TimeoutSec=infinity

# 调整此进程被 Linux 内存不足 (Out-Of-Memory, OOM) killer 杀死的可能性评分。
# -1000 是最低可能值,使得 MinIO 进程在系统内存紧张时极不容易被 OOM killer 选中杀死,从而保护其稳定运行。
OOMScoreAdjust=-1000

# 当停止服务时,如果进程在收到停止信号(默认为 SIGTERM)后,在超时时间(TimeoutStopSec,此处默认为 TimeoutSec=infinity)内没有退出,
# systemd 通常会发送 SIGKILL 强制终止。将此项设为 'no' 可以阻止 systemd 发送 SIGKILL。
# 这依赖于 MinIO 进程能够正确处理 SIGTERM 信号并最终自行优雅退出,无论花费多长时间。
SendSIGKILL=no

[Install]
# 指定当此服务被启用 (enabled) 时(通过 `systemctl enable minio.service`),
# 应在 `multi-user.target` 的 `.wants` 目录下创建一个符号链接。
# 这确保了当系统启动到标准的多用户运行级别 (runlevel) 时,该服务会自动启动。
WantedBy=multi-user.target

# 信息性注释,很可能是在软件包构建过程中自动添加的。
# 它指明了生成此服务文件的源项目名称和版本。
# ${...} 语法表明是构建时被替换的变量。
# Built for ${project.name}-${project.version} (${project.name})

我们只需要看见这行就行

EnvironmentFile=-/etc/default/minio

里面已经指定了默认配置文件,看到这里你的疑惑应该已经消失了.

继续配置环境变量

有些人使用Centos 一类的系统系统自带的是vim编辑器,nano肯定没咋用过,本教程也就顺带提一嘴.

键入sudo nano /etc/default/minio之后我们会来到这个界面

yaqblfriyr.png

我们需要配置的也就几个环境变量

# MinIO 默认配置文件

# 设置数据存储卷路径
MINIO_VOLUMES="/data/minio"

# 设置传递给 minio server 的命令行参数
# API 监听端口 9001, 控制台监听端口 9000
MINIO_OPTS="--address :9001 --console-address :9001"

# 设置 MinIO Root 用户凭证
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=admin

修改成自己的信息后复制,在界面直接按住Ctrl+Shift+V即可粘贴

qcemzdmcef.png

保存步骤:

Ctrl+X,然后按 Y,最后按 Enter 保存退出。

重新加载 Systemd 配置并启动 MinIO 服务

sudo systemctl daemon-reload
sudo systemctl enable minio
sudo systemctl start minio
sudo systemctl status minio

sudo systemctl daemon-reload 重新加载systemctl 配置文件

sudo systemctl enable minio 开机自启动MinIO

sudo systemctl start minio 启动MinIO

sudo systemctl status minio 查看MinIO服务状态

如果你是按照本教程一步一步来的话运行这四条命令,它的结果应该是

pnascuhoud.png

为什么报错了?有人看见自己辛辛苦苦跟着作者在敲了半天键盘,最后跑不起来,心态都没了.没事的跑不起来很正常,我们来排查就行,我写这个的目的也是让大家有排查的手段。

先看日志我们输入这个命令

journalctl -u minio.service -n 100 --no-pager
  • -u minio.service:只显示这个服务的日志。

  • -n 100:显示最近的 100 行(可以根据需要调整)。

  • --no-pager:直接输出到终端,而不是使用 less 等分页器。

  • 你也可以去掉 -n 100 来查看所有相关日志,或者使用 -f 来实时跟踪新日志。

dclcjixane.png

看错误信息,原来是我们控制端和API端端口配置成相同的了

sudo nano /etc/default/minio

我们修正一下

# API 监听端口 9001, 控制台监听端口 9000
MINIO_OPTS="--address :9001 --console-address :9000"

再次运行,怎么还是失败,我们还是老规矩来排查

gkuawouswl.png

原来是我们密码最少要8位数字,在配置文件里面把密码修改一下,再次运行

sudo systemctl daemon-reload
sudo systemctl enable minio
sudo systemctl start minio
sudo systemctl status minio

abmpokyubu.png

这不就跑起来了吗

MinIO基础使用教程

我们访问控制台端口我这里是

http://192.168.111.10:9000/login

bixrinsrtd.png

登录之后界面是

suumgutvek.png

我们点击Create a Bucket.

qmhgfcnncq.png

我们随便取一个bucket名字就行

gizdnaxzcn.png

我们点击刚才创建好的bucket,更改权限为public,方便我们外部访问,我们随便上传一个图片

lnpscoakvr.png

如何外部访问呢,这里就要用到我们的API端口url格式是IP+API端口/bucket/文件名字

比如我们实例这个url就应该是:http://192.168.111.10:9001/local-debian/2025-04-27_21-17-54.png

sfetvxgnup.png

如何在支持S3的程序上对接呢?

我这里以halo为例

nbgckbbdyq.png

eiszagvsmf.png

bucket名称填你自己的bucket名称

EndPoint填API端点

风格是Path Style

那俩key在

ttykzadaio.png

region在这里

vgowdjuuzy.png

设置好后记得点击重启

zpzoupnhmy.png

这样就对接好了

Nginx配置反向代理

我们使用这个对象存储肯定不能将ip和端口直接暴露出去吧,我们采用nginx来反代

安装Nginx

sudo apt install nginx -y

查看状态

sudo systemctl status nginx

确认 Nginx 正在运行 (active (running))。

推荐配置

  • 修改 MinIO 监听地址: 为了提高安全性,最好让 MinIO 只监听本地回环地址 (127.0.0.1),这样只有本机上的进程(比如 Nginx)才能连接它。

  • 编辑 MinIO 配置文件:

sudo nano /etc/default/minio
  • 修改 MINIO_OPTS 行,在端口前加上 127.0.0.1:

# 原来的配置:
# MINIO_OPTS="--address :9001 --console-address :9000"
# 修改为:
MINIO_OPTS="--address 127.0.0.1:9001 --console-address 127.0.0.1:9000"

保存文件 (Ctrl+X, Y, Enter)。

  • 重启 MinIO 服务以应用更改:

sudo systemctl restart minio.service

创建Nginx配置文件

因为我们这俩都是MinIO的,我们就写到一个文件里面去

sudo nano /etc/nginx/sites-available/minio.conf

我们假定api域名为test1.com 控制台域名为test2.com

# /etc/nginx/sites-available/minio.conf

# --- MinIO API Server Block (test1.com) ---
server {
    listen 80;
    listen [::]:80;
    server_name test1.com;

    # 强制跳转到 HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name test1.com;

    # SSL Certificate Configuration
    ssl_certificate /etc/letsencrypt/live/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/privkey.pem;

    # SSL Security Parameters (as provided)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
    ssl_prefer_server_ciphers on; 
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s; # Google Public DNS, 确认服务器可访问
    resolver_timeout 5s;

    # Increase max body size for uploads (adjust as needed)
    client_max_body_size 5G;

    # Proxy API requests to MinIO API port (127.0.0.1:9001)
    location / {
        # Handle CORS preflight requests if necessary
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '*' always; # Consider restricting origin
            add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, DELETE, HEAD' always;
            add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Content-Length, Host, X-Amz-Date, X-Amz-Content-Sha256, X-Amz-User-Agent' always;
            add_header 'Access-Control-Max-Age' 1728000 always;
            add_header 'Content-Type' 'text/plain charset=UTF-8' always;
            add_header 'Content-Length' 0 always;
            return 204;
         }

        proxy_set_header Host $http_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;
        # Important for MinIO to know connection is secure

        proxy_connect_timeout 300;
        # Default is 60, increase if you have backend issues.
        proxy_http_version 1.1; # Recommended for keepalive connections
        proxy_set_header Connection ""; # Clear close connection from client

        # Buffering can impact large uploads/downloads, consider off if issues arise
        # proxy_buffering off;

        # Ignore headers from client related to acceleration / caching
        proxy_ignore_headers X-Accel-Redirect X-Accel-Buffering X-Accel-Limit-Rate X-Accel-Charset Expires Cache-Control Set-Cookie;
        proxy_ignore_client_abort on;

        proxy_pass http://127.0.0.1:9001;
    }
}

# --- MinIO Console Server Block (test2.com) ---
server {
    listen 80;
    listen [::]:80;
    server_name test2.com;

    # 强制跳转到 HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name test2.com;

    # SSL Certificate Configuration (Use the same certificate)
    ssl_certificate /etc/letsencrypt/live/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/privkey.pem;

    # SSL Security Parameters (Use the same parameters)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    # Proxy Console requests to MinIO Console port (127.0.0.1:9000)
    location / {
        proxy_set_header Host $http_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;

        # Required for MinIO Console WebSocket functionality
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Consider turning off buffering for better Console responsiveness
        # proxy_buffering off;

        proxy_pass http://127.0.0.1:9000;
    }
}

请注意修改里面的信息,SSL证书路径以及对应域名和端口

修改完后保存

创建符号链接

sudo ln -s /etc/nginx/sites-available/minio.conf /etc/nginx/sites-enabled/

(如果存在默认的 Nginx 配置链接 defaultsites-enabled 中,你可能需要移除它:sudo rm /etc/nginx/sites-enabled/default

测试Nginx配置

sudo nginx -t

确保输出显示 syntax is oktest is successful

重新加载Nginx

sudo systemctl reload nginx

这样之后去域名DNS解析一下就能用域名访问了

服务器防火墙配置

这里我推荐使用ufw (Uncomplicated Firewall) 是一个用户友好的 iptables/nftables 前端,在 Debian 上很常用

安装ufw

sudo apt update
sudo apt install ufw -y

检测ufw状态

sudo ufw status

初始状态应该是 "inactive"

设置默认策略

推荐设置默认拒绝所有传入连接,允许所有传出连接.

sudo ufw default deny incoming
sudo ufw default allow outgoing

允许必要的端口

  • SSH (端口 22): 允许你通过 SSH 连接到服务器。这一步非常重要,千万不要忘记! 如果你的 SSH 端口不是 22,请替换。

sudo ufw allow ssh
# 或者如果你确定是 22 端口
# sudo ufw allow 22/tcp
  • HTTP (端口 80): 允许 Nginx 接收 HTTP 请求。

sudo ufw allow http
# 或者
# sudo ufw allow 80/tcp
  • HTTPS (端口 443): 允许 Nginx 接收 HTTPS 请求

sudo ufw allow https
# 或者
# sudo ufw allow 443/tcp

启用防火墙

sudo ufw enable

系统可能会提示你此操作可能中断 SSH 连接,输入 y 并回车确认。

再次检查 ufw 状态:

sudo ufw status verbose

你应该能看到防火墙是 active 状态,并且允许了 ssh (或其他指定的端口), http, https。

如何删除某个端口

sudo ufw delete allow 端口/tcp
sudo ufw reload

如何卸载MinIO

先停掉进程

sudo systemctl stop minio
sudo systemctl disable minio

卸载 MinIO DEB 包

使用 dpkg 命令卸载 MinIO 软件包。

sudo dpkg -r minio

如果需要移除配置文件(通常不推荐,但如果想彻底干净,可以使用 --purge):

# 谨慎使用 --purge,这会移除配置文件
# sudo dpkg --purge minio

移除 MinIO 数据目录

删除 MinIO 存储数据和配置的目录。请务必确认这是正确的目录,以免误删重要数据。在之前的文档中,我们使用了 /data/minio

sudo rm -rf /data/minio

(请将 /data/minio 替换为你实际使用的 MinIO 数据目录路径)

移除 MinIO 用户

删除为 MinIO 服务创建的系统用户。

sudo userdel minio-user

重新加载 Systemd 配置

在移除服务文件后,重新加载 Systemd 配置。

sudo systemctl daemon-reload