MinIOをUbuntu 24.04のVPSで自前運用する方法
Ubuntu 24.04のVPS 1台でMinIOを構築します。検証済みソースからのビルド、systemd設定、mc、署名付きURL、resticのS3バックアップ先まで、Community Editionの変更点も解説します。
MinIO のセルフホスト型オブジェクトストレージで得られるもの
MinIO は Amazon S3 API に対応するセルフホスト型オブジェクトストレージです。restic または S3 SDK を自分のサーバーに接続し、エンドポイントの設定を 1 か所変更すれば、日常的なオブジェクトの読み取り、書き込み、一覧表示、presigned link の利用に必要な作業は完了します。ただし、互換性があることと同一であることは別です。たとえば MinIO は Amazon のオブジェクト ACL を実装していません。MinIO のメンテナーも、実装する意図はないと明言しています。そのため、ACL の動作に依存するアプリケーションでは、エンドポイントを変更するだけでは不十分です。このガイドでは、Ubuntu 24.04 上に単一ノードを構築します。検証済みのソースからコンパイルしたバイナリ、専用の system user、root の認証情報を unit file に含めない systemd unit、そして restic のバックアップ先となる bucket を用意します。
S3(simple storage service)はファイルシステムではなく、HTTP API です。bucket 内の key に対してオブジェクトを PUT し、GET で取得します。標準的な bucket では、部分的な書き込みも rename もありません。例外は Amazon の S3 Express One Zone directory bucket です。これらには独自の append および rename 用の呼び出しがあります。ただし、これは 1 つの storage class に限られ、このガイドでは利用しません。標準モデルでは、オブジェクトが完全な状態で到着するか、到着しないかのどちらかであるため、バックアップツールはこのモデルに適しています。
1 つのノードには、データのコピーが 1 つだけ保存されます。これが選択するトレードオフです。VPS の料金で、自分が管理する S3 endpoint を利用できます。一方で、クラウドプロバイダーが担っていたすべての作業も引き継ぎます。故障したディスクの交換から、サーバーソフトウェアへのパッチ適用までが対象です。終盤のセクションでは、このトレードオフが適している状況を明確に説明します。
2026 年 10 月時点の MinIO Community Edition の状況
この先の構築に進む前に、ここを確認してください。最近、状況が変わりました。2025 年 5 月、MinIO は Community Edition の Web コンソールから管理機能を削除しました。ブラウザーで利用できるのはオブジェクトブラウザーだけです。そのため、バケットとアクセスキーは mc コマンドラインクライアントで管理します。
2025 年後半、MinIO はコンパイル済みの Community Edition バイナリの公開も停止しました。プロジェクトの README には、Community Edition はソースコードのみで配布されると記載されています。また、2026 年 4 月以降、minio/minio リポジトリは THIS REPOSITORY IS NO LONGER MAINTAINED という通知とともにアーカイブされています。以前のダウンロードサーバーも、Community Edition のファイルを提供しなくなりました。2026 年 10 月 20 日に確認したところ、このガイドが以前ダウンロードに使用していた dl.min.io のパスはすべて、サーバーバイナリ、クライアントバイナリ、チェックサムファイルを含めて 410 Gone を返しました。これは障害ではなく、意図的な削除です。そのサーバーに残っている唯一の mc バイナリは /aistor/mc/release/ の AIStor Client です。これは商用ラインに属します。現在、min.io のダウンロードページには AIStor Server、AIStor Client、AIStor SDK、いくつかの AIStor アドオンが掲載されています。さらに、スタンドアロン構成を運用する開発者、研究者、小規模組織向けと説明された無料の AIStor tier も掲載されています。Community Edition のビルドはありません。
ソースコードはまだ存在し、最後のバイナリより新しい状態です。最後の Community Edition リリースは RELEASE.2025-10-15T17-29-55Z です。2025 年 10 月 16 日にセキュリティリリースとして公開され、service accounts と STS における session policy bypass を利用した権限昇格を修正しました。リリースノートでは、すべてのユーザーに直ちにアップグレードするよう推奨しています。最後のコンパイル済みバイナリは 2025 年 9 月のビルドです。そのため、この修正は適用されていません。このガイドでは 10 月のリリースをコンパイルします。リポジトリはアーカイブされているため、これが Community Edition に提供される最後の修正でもあります。
この事実が、このガイドの以降の構成を決めます。ここで MinIO が 127.0.0.1 で待ち受け、管理下のプロキシを通じてのみインターネットに接続するのは、そのためです。
MinIO のバイナリをインストールし、ダウンロードを検証する
MinIO は Go で記述されています。ベンダーの README では、Go 1.24 以降が必要な単一の go install コマンドでビルドします。まず、公式 tarball から Go をインストールします。2026 年 10 月 20 日時点で、go.dev/dl の現行安定版は go1.27.3 です。これは 2026 年 10 月 19 日にリリースされ、crypto/x509 パッケージのセキュリティ修正が含まれています。以下のハッシュは、そのページに掲載されている linux-amd64 アーカイブの値です。新しい Go を選ぶ場合は、同じページからそのハッシュを取得してください。-f フラグを指定すると、HTTP エラー時に curl は失敗します。これを指定しないと、要求した名前でエラーページを保存してしまい、404 ページを展開してアーカイブではない理由が分からなくなることがあります。
cd /tmp
GOVER=go1.27.3
curl -fsSL "https://go.dev/dl/$GOVER.linux-amd64.tar.gz" -o go.tar.gz2 つのハッシュを比較します。比較するのはハッシュだけです。
published=65efbc80fdc1fa2cd2631cad5b481777a68e8725f34e89f50fc6ac714e379b40
downloaded=$(sha256sum go.tar.gz | awk '{print $1}')
[ "$published" = "$downloaded" ] && echo "checksum ok"この検証で何が確認できるかを明確に理解してください。一致すれば、ダウンロードが完全であり、転送中に破損または改変されていないことを確認できます。ただし、ベンダーが信頼できることは証明できません。これは別の問題であり、sha256sum コマンドでは解決できません。
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go.tar.gz
export PATH=$PATH:/usr/local/go/bin
go version次に、通常のユーザーとして最終的な community release をビルドします。go install は、MinIO 自身のソースを含め、ダウンロードするすべてのモジュールを Go の公開チェックサムデータベースである sum.golang.org と照合します。そのため、改ざんまたは置換されたモジュールがあると、バイナリを生成せずにセキュリティエラーでビルドが停止します。
go install github.com/minio/minio@RELEASE.2025-10-15T17-29-55Z
sudo install -o root -g root -m 755 ~/go/bin/minio /usr/local/bin/minio
minio --version
go version -m /usr/local/bin/minio | head -n 3minio --version は、以前ならリリース名が表示されていた箇所に DEVELOPMENT.GOGET と表示します。これは、go install がベンダーのバイナリに情報を書き込むために使用したビルドフラグを適用しないためです。go version -m は、Go がすべてのバイナリに埋め込むモジュール情報を読み取ります。mod github.com/minio/minio 行には、ビルドしたコミットが示されます。ここで Permission denied になっている場合はモードが正しくありません。command not found は、/usr/local/bin が PATH 上に存在しないことを示します。VPS のメモリがコンパイルに不足する場合は、同じ go install を同じアーキテクチャの別の Linux マシンで実行し、バイナリをコピーしてください。
システムユーザーとデータディレクトリを作成する
MinIOはネットワークからのアップロードを受け付けるため、rootとして実行しないでください。ホームディレクトリとログインシェルを持たないアカウントを割り当てます。
sudo groupadd -r minio-user
sudo useradd -M -r -g minio-user -s /usr/sbin/nologin minio-user
sudo mkdir -p /var/lib/minio/data
sudo chown -R minio-user:minio-user /var/lib/minio
sudo chmod 750 /var/lib/minio-rはUIDが1000未満のシステムアカウントを作成します。これにより、人が使用する範囲から分離できます。-Mはホームディレクトリの作成を省略します。ログインしないアカウントには、保持するホームディレクトリがないためです。id minio-userで結果を確認し、stat -c '%U %a' /var/lib/minioでも確認します。後者はminio-user 750を出力するはずです。
データディレクトリは、そのユーザーが読み取れるだけでなく、書き込める必要があります。初回起動時、MinIOはボリューム内に.minio.sysディレクトリを作成して独自の設定を保存します。そのため、ディレクトリの所有者がrootだと、MinIOは起動中に終了し、メッセージの末尾にpermission deniedと表示されます。この方法で実行するすべてのサービスに同じ規則が適用されます。VPSでの最小権限のサービスユーザーで詳しく説明しています。
root の認証情報を環境ファイルに格納する
root の認証情報ではすべてのバケットにアクセスできるため、全ユーザーから読み取り可能な unit file に記載してはいけません。まず適切なモードでファイルを作成し、その後で内容を書き込みます。これにより、パスワードが読み取り可能なファイルに一瞬でも存在することを防げます。
sudo install -o root -g root -m 600 /dev/null /etc/default/minio
printf 'MINIO_ROOT_USER=minio-root\nMINIO_ROOT_PASSWORD=%s\nMINIO_VOLUMES="/var/lib/minio/data"\nMINIO_OPTS="--address 127.0.0.1:9000 --console-address 127.0.0.1:9001"\n' "$(openssl rand -base64 24)" | sudo tee /etc/default/minio > /dev/null
sudo sed -n 's/^MINIO_ROOT_PASSWORD=//p' /etc/default/miniotee は既存のファイルを再作成せずに切り詰めるため、モードは 600 のままで、所有者も root のままです。これは意図した動作です。systemd は権限を User= に落とす前に、root として EnvironmentFile を読み取ります。そのため、サービスアカウントが自身の認証情報を読み取る必要はありません。サービスの起動後は、sudo -u minio-user cat /etc/default/minio で確認できます。このコマンドは Permission denied を出力する必要があります。
起動する前に、MinIO の 2 つの動作を把握しておいてください。環境に MINIO_ROOT_USER も MINIO_ROOT_PASSWORD もない場合、MinIO は起動を拒否しません。文書化されたデフォルト認証情報 minioadmin:minioadmin で起動します。これはスキャナーが最初に試す認証情報の組み合わせであり、その状態でも完全に正常に動作しているように見えます。8 文字未満のパスワードは別の扱いになります。MinIO は起動時に、認証情報が無効であることを示すエラーを出して終了します。access key には 3 文字以上、secret key には 8 文字以上が必要だからです。
MINIO_VOLUMES はデータパスで、MINIO_OPTS にはフラグを指定します。127.0.0.1 に bind すると、この VPS の外部から S3 API にアクセスできなくなります。これは適切なデフォルト設定です。後で、証明書を保持する proxy 経由で意図的に公開します。
systemd ユニットを作成する
/etc/systemd/system/minio.service を作成します。
[Unit]
Description=MinIO object storage
Documentation=https://github.com/minio/minio
Wants=network-online.target
After=network-online.target
[Service]
User=minio-user
Group=minio-user
EnvironmentFile=/etc/default/minio
ExecStart=/usr/local/bin/minio server $MINIO_VOLUMES $MINIO_OPTS
Restart=always
RestartSec=5
LimitNOFILE=65536
NoNewPrivileges=true
[Install]
WantedBy=multi-user.targetEnvironmentFile の先頭に - がないのは、タイプミスではなく意図的な設計です。ハイフンがあると、systemd はファイルが存在しなくても無視して MinIO を起動します。そのため、ファイルを削除した場合やパスを誤記した場合、minioadmin:minioadmin で実行されるサーバーが通知なしに起動します。ハイフンがない場合、ファイルが存在しないと MinIO が実行される前にユニットが失敗し、journalctl -u minio に Failed to load environment files: No such file or directory が表示されます。起動を拒否するユニットのほうが、デフォルトパスワードを使用してサーバーが気付かないまま接続を受け入れるより、容易に発見できます。
$MINIO_VOLUMES と $MINIO_OPTS を引用符で囲んでいないのは意図的です。systemd は、引用符で囲んでいない変数を空白で分割し、個別の引数にするためです。これにより、MINIO_OPTS の4つの単語が minio server への4つの引数になります。LimitNOFILE=65536 はファイルディスクリプターの上限を引き上げます。開いている接続とデータファイルはそれぞれ1つのディスクリプターを消費するため、デフォルト値の1024は負荷が高いと不足します。
sudo systemctl daemon-reload
sudo systemctl enable --now minio
systemctl is-active minio
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:9000/minio/health/liveis-active は active を出力し、ヘルスエンドポイントは 200 を返すはずです。journalctl -u minio -n 20 --no-pager には、サーバーがリッスンしているAPIアドレスが表示されます。ユニットが再起動を繰り返すと、systemd は再試行を停止し、Start request repeated too quickly をログに記録します。これは、MinIO が試行のたびに終了していることを意味します。原因はそのメッセージより上の行に出力されるため、上方向に読み進めてください。
分離を強化するには、[Service] セクションに ProtectSystem=full と ProtectHome=true を追加します。どちらもホストカーネルの mount namespace を必要とします。OpenVZ や LXC など、ホストカーネルを共有するコンテナ仮想化環境では失敗することがあり、その場合、ユニットは status=226/NAMESPACE を報告します。この2行を削除すると起動します。ユニット自体は通常のもので、残りのディレクティブについては VPS での systemd サービスとタイマーで説明しています。
mc をインストールし、往復転送を検証する
MinIO クライアントは mc です。apt install mc ではインストールしないでください。このパッケージは MinIO とは無関係なファイルマネージャーである Midnight Commander です。
dl.min.io には現在も mc バイナリがありますが、コミュニティ版ではありません。以前のコミュニティ版のパスである https://dl.min.io/client/mc/release/linux-amd64/mc は、410 Gone を返します。現在 MinIO がそこで提供しているのは https://dl.min.io/aistor/mc/release/linux-amd64/mc の AIStor Client です。AIStor CLI のリファレンスでは、このクライアントをライセンス済みの AIStor Server 環境専用の機能を持つものとして案内しています。このリファレンスには、コミュニティ版サーバーに接続できるとは記載されていません。そのため、このガイドではコミュニティ版クライアントを使用します。minio/mc リポジトリは 2026 年 7 月以降アーカイブされているため、最後のリリースである RELEASE.2025-08-13T08-35-41Z を、同じ Go ツールチェーンでビルドします。このダウンロードもチェックサムデータベースで検証できます。
go install github.com/minio/mc@RELEASE.2025-08-13T08-35-41Z
sudo install -o root -g root -m 755 ~/go/bin/mc /usr/local/bin/mcサーバーをエイリアスとして登録し、オブジェクトをサーバー経由で転送します。
MINIO_PASS=$(sudo sed -n 's/^MINIO_ROOT_PASSWORD=//p' /etc/default/minio)
mc alias set local http://127.0.0.1:9000 minio-root "$MINIO_PASS"
mc mb local/backups
echo "hello object storage" > /tmp/hello.txt
mc cp /tmp/hello.txt local/backups/hello.txt
mc ls local/backups
mc cat local/backups/hello.txtmc ls では、サイズ付きで hello.txt が一覧表示されます。mc cat では hello object storage が出力されます。この往復転送が、サーバーが動作していることの実証になります。ほかのクライアントも同じ署名付き S3 リクエストを送信するためです。別の方法でも確認する場合は、mc admin info local でサーバーのステータスを表示できます。
サーバーがまだ空の間に、もう 1 つ確認します。
mc alias set defaultcheck http://127.0.0.1:9000 minioadmin minioadminこのコマンドは失敗する必要があります。成功した場合、環境ファイルがプロセスに渡っておらず、サーバーがデフォルトの認証情報で動作しています。ほかの処理をこのマシンで実行する前に修正してください。
mc はエイリアスを ~/.mc/config.json に平文で保存します。そのため、認証情報はコマンドを実行したユーザーのホームディレクトリに置かれます。sudo のもとで mc を実行すると、root の認証情報が /root/.mc/config.json に保存されます。root 用のエイリアスは 1 つの管理者アカウントに限定し、各アプリケーションには固有のキーを割り当ててください。
署名付き URL で 1 つのオブジェクトを配布する
署名付き URL は、署名と有効期限が付加された通常の HTTPS リンクです。このリンクを知っている人は、アカウントやクライアントを使わずに、その 1 つのオブジェクトを取得できます。
mc share download --expire 12h local/backups/hello.txt出力のクエリ文字列には X-Amz-Signature と X-Amz-Expires が含まれます。ここでは、2 つの点に注意してください。リンクは使用した alias の endpoint を基に生成されます。そのため、127.0.0.1 上の alias から生成したリンクは、このマシンでしか開けません。送付するリンクには、公開ホスト名を指定した別の alias を作成してください。
また、リンクごとに取り消すボタンはありません。署名は、有効期限が切れるか、署名に使用した key が削除または変更されるまで有効です。root の認証情報で署名したリンクの場合、key の変更には認証情報のローテーションが必要です。そのため、実際の対策は短い有効期限を設定することです。S3 の署名形式で指定できる最大期間は 7 日です。
restic専用のkeyとbucketを作成する
rootの認証情報ではすべてのbucketを読み取り、削除できます。そのため、バックアップジョブでrootの認証情報を使用してはいけません。bucket、対象のbucketだけに適用するpolicy、およびそれ以外の権限を持たないuserを作成します。
mc mb local/restic
cat > /tmp/restic-rw.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket", "s3:GetBucketLocation"],
"Resource": ["arn:aws:s3:::restic"]
},
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
"Resource": ["arn:aws:s3:::restic/*"]
}
]
}
EOF
RESTIC_KEY=$(openssl rand -base64 24)
mc admin policy create local restic-rw /tmp/restic-rw.json
mc admin user add local restic-backup "$RESTIC_KEY"
mc admin policy attach local restic-rw --user restic-backupMinIOには組み込みのreadwritepolicyがあります。これを使えばコマンドを1つ減らせますが、サーバー上のすべてのbucketへの完全なアクセス権が付与されます。上記のpolicyでは、意図的にbucket名を2回指定しています。1回目はbucketの一覧表示に必要なarn:aws:s3:::resticとして、2回目はbucket内のobjectに必要なarn:aws:s3:::restic/*として指定しています。S3ではbucketとそのobjectは別々のresourceです。そのため、どちらか一方だけを指定したpolicyは、clientの問題に見える形で失敗します。
信頼する前に、制限をテストします。
mc alias set resticuser http://127.0.0.1:9000 restic-backup "$RESTIC_KEY"
mc ls resticuser/restic
mc ls resticuser/backups最初のlsは成功し、2つ目はAccess Deniedで失敗します。テストしていないpolicyは推測にすぎません。
次に、resticからbucketを使用します。resticは標準のAWS環境変数からS3の認証情報を読み取るため、restic固有の認証情報ファイルは必要ありません。
sudo apt install -y restic
export AWS_ACCESS_KEY_ID=restic-backup
export AWS_SECRET_ACCESS_KEY="$RESTIC_KEY"
restic -r s3:http://127.0.0.1:9000/restic init
restic -r s3:http://127.0.0.1:9000/restic backup /etc
restic -r s3:http://127.0.0.1:9000/restic snapshotsrestic initではrepositoryのpasswordを要求されます。このpasswordによってrepositoryが暗号化されるため、MinIOに保存されるのは常にciphertextだけです。passwordを失うと、バックアップも失われます。systemd timerで起動する処理には入力用のterminalがありません。そのため、スケジュールされたバックアップではRESTIC_PASSWORD_FILEをmode 600のファイルに設定します。
上記のどのコマンドよりも重要な配置ルールがあります。保護対象のdataと同じVPS上にrestic repositoryを置いても、防げるのは不正なrmだけです。それ以外の障害からは保護できません。MinIO nodeは別のマシンに配置してください。できれば別のregionに配置します。VPS上のresticバックアップでは、この構成を前提にスケジュール設定と保持期間を説明しています。
nginxでTLSを終端する
MinIOはlocalhostで動作するため、公開側の窓口はnginxです。まず、certbotとnginxでLet's Encrypt証明書を取得するの説明に従って証明書を発行し、その後、次のserver blockを使用します。
server {
listen 443 ssl;
server_name s3.example.com;
ignore_invalid_headers off;
client_max_body_size 0;
proxy_buffering off;
proxy_request_buffering off;
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;
proxy_connect_timeout 300;
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_pass http://127.0.0.1:9000;
}
}これらの行のいくつかは重要です。client_max_body_size 0はデフォルトの1 MBのbody制限を解除します。この制限があると、MinIOがリクエストを受け取る前に、1 MBを超えるアップロードが413 Request Entity Too Largeで拒否されます。proxy_request_buffering offはアップロードをそのまま転送します。デフォルト設定ではリクエスト全体を一時ファイルに保存するため、大きなオブジェクトではディスク容量が2倍必要になります。proxy_set_header Host $http_hostは見落としやすい設定です。S3の署名にはHostヘッダーが含まれるため、プロキシがこのヘッダーを書き換えると、アクセスログには通常どおりリクエストが到着しているように見えても、すべてのリクエストがSignatureDoesNotMatchで失敗します。
MinIOには公開名も設定してください。これにより、生成されるリンクがlocalhostではなくプロキシを指すようになります。
echo 'MINIO_SERVER_URL=https://s3.example.com' | sudo tee -a /etc/default/minio
sudo systemctl restart minioファイアウォール設定は最小限で構いません。SSHとHTTPSを許可し、ポート9000と9001にはルールを設定しないでください。127.0.0.1にバインドされたアドレスは、ファイアウォールの設定に関係なく別のマシンから到達できないためです。コマンドについては、VPSでのufwファイアウォールの基本を参照してください。
シングルノードの MinIO で十分な場合と、本格的な S3 が必要な場合
ここでいうシングルノードは 1 台のドライブを意味します。そのため、デプロイメント内にパリティも 2 つ目のコピーもなく、各オブジェクトの耐久性は 1 台の VPS のディスクの耐久性に依存します。ホステッド版のコミュニティドキュメントが 2025 年 10 月に取り下げられて以降、minio/docs リポジトリにソースとしてのみ残っている MinIO の公式ドキュメントでは、スタンドアロンデプロイメントを初期開発と評価向けと説明し、本番環境では推奨していません。バケットでは Object Lock を有効にできますが、1 台の VPS では S3 API による削除を止めるだけです。マシン上の root はディスク上のファイルを削除できるため、この構成で不変の保持ポリシーを保証してはいけません。
別リージョンの 2 台目の VPS を restic の保存先にする用途や、開発作業と CI アーティファクト用の S3 エンドポイントには適しています。バケットを失っても、再構築が必要になるだけで済む場合に向いています。小規模なアプリケーションのユーザーアップロードにも適しています。ただし、復旧計画を自分で管理し、実際にリストアをテストしていることが条件です。
契約や規制によって Object Lock またはマルチリージョンの耐久性が求められる場合は、managed S3 を選択してください。ディスク容量の枯渇で 03:00 に呼び出される担当者になりたくない場合も同様です。コードが凍結されていることも、選択理由として正直に考慮すべき点です。2026 年 10 月 20 日時点でコミュニティエディションはアーカイブされ、保守も終了しています。このガイドがコンパイルするのは最後のリリースである RELEASE.2025-10-15T17-29-55Z です。これ以降に問題が修正されることはありません。そのため、これを実行するなら、その状態を受け入れる必要があります。または、MinIO の商用 AIStor 系列や別のセルフホスト型ストレージへ移行してください。セルフホスト型 MinIO の代替製品で比較しています。
よく問題になるため、1 つ境界を明確にしておきます。オブジェクトストレージはデータベースではありません。標準的なバケットでは、書き込みのたびにオブジェクト全体が置き換えられます。Amazon が S3 Express One Zone に追加した append 呼び出しでさえ、データを末尾に追加するだけです。そのため、S3 バケット上の稼働中の SQL ファイルは低速で安全ではありません。データベースはローカルディスクに置き、代わりにバケットへバックアップしてください。VPS で SQLite を本番運用する方法で、この分離について説明しています。
障害のパターンと表示されるメッセージ
systemctl enable --nowの直後に unit が失敗する。 journalctl -u minio -n 30 --no-pagerを確認してください。Failed to load environment files: No such file or directoryは、unit 内で /etc/default/minioが指定されていないか、そのパスの記述が誤っていることを示します。permission deniedで終わるメッセージは、サービスアカウントにデータディレクトリへの書き込み権限がないことを示します。そのため、stat -c '%U' /var/lib/minio/dataの出力が minio-userになることを確認してください。
minioadmin:minioadminでログインできてしまう。 環境ファイルがプロセスに渡っていません。unit に EnvironmentFile=/etc/default/minioが含まれていることを確認し、sudo systemctl daemon-reloadを実行してからサービスを再起動してください。MinIO は起動時に root credentials を1回だけ読み込むため、再起動せずにこのファイルを編集しても変更は反映されません。
起動時に Address already in useが発生する。 別のプロセスが port 9000 を使用しています。MinIO の port を変更する前に、sudo ss -ltnp | grep :9000で使用中のプロセスを確認してください。
プロキシ経由で 1 MB を超えるアップロードが失敗する。 nginx が 413 Request Entity Too Largeを返し、MinIO はリクエストを受信していません。server block に client_max_body_size 0を設定してください。
SignatureDoesNotMatchが発生する。 secret key が誤っているか、client と MinIO の間にある何かが、署名の対象となる Hostヘッダーを書き換えています。
RequestTimeTooSkewedが発生する。 client または server の時刻が誤っています。署名付き S3 リクエストには必ず timestamp が含まれます。MinIO は Amazon S3 と同様に、ヘッダー署名されたリクエストの timestamp が自身の時刻から 15 分を超えてずれている場合、そのリクエストを拒否します。Presigned link は有効期限に基づいて検証されます。timedatectlを確認し、時刻同期が有効になっていることを確認してください。
存在すると分かっている bucket で Access Deniedが発生する。 key の対象が別の bucket になっています。mc admin policy info local restic-rwで policy が実際に許可している内容を出力し、resource 行に記載された bucket 名を比較してください。
FAQ
単一ノードの MinIO で実際のバックアップに十分対応できますか?
保護対象のデータとは別のマシンで動作する restic の保存先としては十分です。ただし、唯一のコピーとしては不十分です。単一ドライブ構成にはパリティがまったくないため、MinIO 内に 2 つ目のコピーは存在しません。その VPS のディスクでデータが失われると、オブジェクトも失われます。別の場所に 2 つ目の保存先を用意し、少なくとも 1 回は両方から復元して、手順が機能することを確認してください。
MinIO のチェックサムファイルで sha256sum -c が失敗するのはなぜですか?
そのファイルは、以前に保存したコピーでのみ見つかります。2026 年 10 月 20 日に確認した時点で、dl.min.io はすべての community binary と checksum file について 410 Gone と回答しているためです。そのファイル内のハッシュの後にあるラベルは、minio.RELEASE.2025-09-07T16-13-09Z のようにリリース名を示します。一方、ダウンロードしたファイルの通常の名前は minio です。sha256sum -c はチェックサムファイル内に記載された名前のファイルを探しますが、見つけられないため、No such file or directory と WARNING: 1 listed file could not be read を報告します。ダウンロード自体には問題ありません。ハッシュ文字列を直接比較し、セキュリティ上の意味を持たないラベルは無視してください。
MinIO の管理 Web コンソールはどこに移動しましたか?
MinIO は 2025 年 5 月に community edition のコンソールから管理機能を削除し、Web インターフェースにはオブジェクトブラウザーだけを残しました。現在、バケットとユーザーは mc クライアントで管理し、mc admin user add や mc admin policy attach などのコマンドを使用します。これは回避策ではなく、community edition で想定されている方法です。そのため、このガイドではすべての操作をコマンドラインから行います。
restic から MinIO を S3 バックエンドとして使用するにはどう設定しますか?
AWS_ACCESS_KEY_ID と AWS_SECRET_ACCESS_KEY に MinIO のアクセスキーとそのシークレットを設定し、s3:https://s3.example.com/restic 形式のリポジトリ文字列を使用します。最後のパス要素がバケット名です。バケットは先に mc mb で作成してください。1 つのバケットに限定されたキーには、バケットを作成する権限がないためです。restic はアップロード前に独自のリポジトリパスワードですべてを暗号化するため、MinIO に保存されるのは暗号文であり、ファイルの内容が MinIO に知られることはありません。
MinIO を nginx の背後で実行する必要はありますか?
クライアントが同じマシン上にない場合は、TLS (transport layer security) が必要です。TLS がなければ、すべてのオブジェクトがアクセスキー ID とリクエスト署名とともに平文でネットワークを通過するためです。シークレットキー自体がクライアントから送信されることはありません。S3 の署名では、シークレットキーをクライアント上で使用して署名を計算するだけだからです。ただし、通信経路上の第三者はデータを読み取ることができ、タイムスタンプが有効な間は取得したリクエストを再送できます。ポート 443 で待ち受け、certbot の証明書を使用するプロキシが、TLS を導入する最も簡単な方法です。証明書の更新処理も MinIO から分離できます。MinIO 自体で TLS を終端することもできます。その場合は、--certs-dir を public.crt と private.key を格納したディレクトリに向けます。ただし、サービスアカウントに更新後の秘密鍵の読み取り権限を付与する必要があり、同じ結果を得るための追加作業が発生します。