OSSのオブジェクトストレージ比較:MinIO vs Ceph vs Garage でS3代替をセルフホストする
オープンソースラボ編集部 ・ 2026年6月13日
OSSのオブジェクトストレージ比較:MinIO vs Ceph vs Garage でS3代替をセルフホストする
AWS S3(月$0.023/GB〜)・Cloudflare R2(月$0.015/GB〜)に対して、MinIO(最もS3互換性が高いOSSオブジェクトストレージ)・Ceph(エンタープライズ分散ストレージ)・Garage(軽量・地理分散対応)はOSSのオブジェクトストレージです。
オブジェクトストレージが必要な場面
- ユーザーアップロードファイル: アバター画像・ドキュメント・動画をS3互換APIで保存
- バックアップ: データベースバックアップ・ログアーカイブを安価なセルフホストストレージへ
- 静的アセット配信: WebアプリのCSS/JS/画像をCDNに流す前のオリジンストレージ
- データパイプライン: ETLでParquet/CSVを一時保存してDuckDB/Sparkで処理
主要ツールの概要
MinIO
2014年に公開されたGo製のS3互換オブジェクトストレージです。GitHubスター50k+。S3 APIと完全互換でAWS S3 SDKをそのまま使え、DockerとKubernetesどちらでも動作します。高可用性のためのイレイジャーコーディング・データライフサイクル管理・バケットレプリケーション・Prometheusメトリクス・WebUIを標準装備。ローカル開発〜本番まで幅広く使えます。
# MinIOをDockerで起動(シングルノード・開発用)
docker run -d --name minio -p 9000:9000 -p 9001:9001 -v ~/minio-data:/data -e MINIO_ROOT_USER=minioadmin -e MINIO_ROOT_PASSWORD=minioadmin minio/minio server /data --console-address ":9001"
# MinIO Console: http://localhost:9001
# S3 API Endpoint: http://localhost:9000
# docker-compose.yml - MinIO 分散モード(本番用・4ノード)
version: '3.8'
services:
minio1:
image: minio/minio:latest
command: server http://minio{1...4}/data --console-address :9001
environment:
MINIO_ROOT_USER: minio-admin
MINIO_ROOT_PASSWORD: minio-secret-password-here
MINIO_VOLUMES: /data
volumes:
- minio1_data:/data
ports:
- "9001:9001"
minio2:
image: minio/minio:latest
command: server http://minio{1...4}/data --console-address :9001
environment:
MINIO_ROOT_USER: minio-admin
MINIO_ROOT_PASSWORD: minio-secret-password-here
volumes:
- minio2_data:/data
# minio3, minio4 も同様
nginx:
image: nginx:alpine
ports:
- "9000:9000"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on: [minio1, minio2]
volumes:
minio1_data:
minio2_data:
# boto3(AWS S3 SDK)でMinIOに接続・操作
import boto3
from botocore.config import Config
# MinIOをS3互換として使用
s3_client = boto3.client(
"s3",
endpoint_url="http://localhost:9000", # MinIOのエンドポイント
aws_access_key_id="minioadmin",
aws_secret_access_key="minioadmin",
config=Config(signature_version="s3v4"),
region_name="us-east-1", # MinIOはリージョン不問
)
# バケットを作成
s3_client.create_bucket(Bucket="user-uploads")
# ファイルのアップロード
s3_client.upload_file(
Filename="/tmp/document.pdf",
Bucket="user-uploads",
Key="users/user-123/documents/report.pdf",
ExtraArgs={
"ContentType": "application/pdf",
"Metadata": {"uploader": "user-123", "original-name": "report.pdf"},
},
)
# 署名付きURLを生成(クライアントに直接アップロードさせる場合)
presigned_upload_url = s3_client.generate_presigned_url(
"put_object",
Params={"Bucket": "user-uploads", "Key": "users/user-123/avatar.jpg", "ContentType": "image/jpeg"},
ExpiresIn=3600, # 1時間有効
)
# 署名付きURL(ダウンロード用)
presigned_download_url = s3_client.generate_presigned_url(
"get_object",
Params={"Bucket": "user-uploads", "Key": "users/user-123/documents/report.pdf"},
ExpiresIn=86400, # 24時間有効
)
// Next.js API RouteでMinIOに直接アップロード(ブラウザ→MinIO)
// src/app/api/upload/presign/route.ts
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { v4 as uuidv4 } from "uuid";
const s3 = new S3Client({
endpoint: process.env.MINIO_ENDPOINT, // http://minio:9000
region: "us-east-1",
credentials: {
accessKeyId: process.env.MINIO_ACCESS_KEY!,
secretAccessKey: process.env.MINIO_SECRET_KEY!,
},
forcePathStyle: true, // MinIOはパス形式を使う
});
export async function POST(req: Request) {
const { filename, contentType } = await req.json();
const key = `uploads/${uuidv4()}-${filename}`;
const command = new PutObjectCommand({
Bucket: "user-uploads",
Key: key,
ContentType: contentType,
});
const presignedUrl = await getSignedUrl(s3, command, { expiresIn: 3600 });
return Response.json({ presignedUrl, key });
}
機能比較表
| 比較項目 | MinIO | Ceph | Garage |
|---|---|---|---|
| S3互換性 | ✅(完全) | ✅ | ✅ |
| セットアップ難易度 | 低 | 高(複雑) | 低 |
| 分散(マルチノード) | ✅ | ✅(最強) | ✅(軽量) |
| 地理分散 | 限定的 | ✅ | ✅(設計重点) |
| エンタープライズ実績 | ✅ | ✅ | 少ない |
| 言語 | Go | C++ | Rust |
| GitHub Stars | 50k+ | 14k+ | 4k+ |
MinIOの画像を配信するためのCDN設定にはDevOpsカテゴリ/categories/devopsのNginx/Caddyリバースプロキシと組み合わせてください。MinIOへのアクセス権限管理にはSecurityカテゴリ/categories/securityのポリシーベースアクセス制御を設定します。
FAQ
Q. MinIOをAWS S3の完全な代替として本番で使えますか?
A. 多くのユースケースでYesです。MinIOはS3のAPIを完全に実装しており、@aws-sdk/client-s3・boto3・mc(MinIO CLI)等がそのまま動きます。注意点: ①CDN: CloudFront相当の機能はMinIo単体にはない(NginxやCloudflareとの組み合わせが必要)②マネージドサービス: 自分でディスク管理・バックアップ・モニタリングが必要③ストレージコスト: セルフホスト専用サーバーを立てるとS3より安くなるのは月1TB以上から④グローバル分散: 複数リージョンへの自動レプリケーションはMinIOのSite Replicationで実現可能(設定が必要)。ユーザー数百〜数千規模の自社サービスなら十分な実績があります。
Q. MinIOのバケットをS3のようにライフサイクルポリシーで管理するには?
A. MinIO Console(WebUI)またはAWS CLIで設定できます。
# AWS CLIでMinIOにライフサイクルルールを設定
aws s3api put-bucket-lifecycle-configuration --endpoint-url http://localhost:9000 --bucket user-uploads --lifecycle-configuration '{
"Rules": [{
"ID": "expire-temp-files",
"Status": "Enabled",
"Filter": {"Prefix": "temp/"},
"Expiration": {"Days": 7}
},{
"ID": "archive-old-uploads",
"Status": "Enabled",
"Filter": {"Prefix": "uploads/"},
"Transitions": [{"Days": 90, "StorageClass": "GLACIER"}]
}]
}'
Q. ローカル開発でS3をモックするにはMinIOとLocalStackどちらを使うべきですか?
A. 用途による: MinIO: S3専用のOSSクライアント・ファイルアップロードのテストがメインで、シンプルにS3 APIだけ使いたい場合。Docker起動が軽量(メモリ100MB程度)。LocalStack: S3以外にSQS・DynamoDB・Lambda・SESなどAWSサービス全体をモックしたい場合。Community版は無料でS3も対応。Pro版(有料)でより多くのサービスに対応。S3しか使わないならMinIOがシンプルで推奨です。
Q. MinIOをSupabase Storageの代替として使えますか?
A. アーキテクチャ上は同じS3互換ストレージなので可能です。Supabase StorageはS3互換APIのラッパーでRow Level Security(RLS)による認証を追加したものです。MinIOでSupabase Storage相当のアクセス制御を実現するには: ①MinIOのポリシーでバケットアクセスを制限②アプリサーバー側で認証後に署名付きURLを発行(Presigned URL)③フロントエンドから直接MinIOにアップロード、というパターンを実装します。SupabaseのRLS相当を独自実装するコストがあるため、既存のSupabaseプロジェクトではSupabase Storageを使い続けるのが無難です。
まとめ
| ユースケース | 推奨ツール |
|---|---|
| S3代替・開発〜本番・DockerもK8sも | MinIO |
| エンタープライズ・マルチプロトコル(S3+Ceph+NFS) | Ceph |
| 軽量・地理分散・ホームラボ・エッジ | Garage |