AWSのS3を利用するアプリケーション開発において、実際にクラウド上のS3とやり取りするのは何かと手間がかかりますよね。
そこで役立つのが、S3互換のオブジェクトストレージである MinIO です。
MinIOを使えば、ローカル環境でS3とほぼ同じ操作を試せるため、開発効率が格段に向上します。
この記事では、Go言語でS3を利用するアプリケーション開発者向けに、Dockerを使ってMinIOを起動し、基本的な操作を行う手順を解説します。
公式サイト
前提条件
- macOS(筆者の動作環境 macOS Sequoia 15.4)
- Docker Desktop for Mac がインストール済み
- Go 1.18 以上
ファイル構成
├ docker
│ └ docker-compose.yml
│
├ download
├ upload
│ └ sample.txt // MinIOへのアップロードサンプルファイル
├ go.mod
├ go.sum
└ main.go
docker-compose設定
version: "3.8"
services:
minio:
image: minio/minio:latest
container_name: minio
ports:
- "9000:9000" # S3 API
- "9001:9001" # MinIO Console
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
command: server /data --console-address ":9001"
volumes:
- minio-data:/data
volumes:
minio-data:
サーバ起動
以下コマンドを叩いてdockerのコンテナを起動します。
$ cd docker
$ docker-compose up -d
起動確認
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4b6330ecda35 minio/minio:latest "/usr/bin/docker-ent…" 4 seconds ago Up 4 seconds 0.0.0.0:9000-9001->9000-9001/tcp minio
起動したコンテナのログも見てみましょう。
$ docker logs 4b6330ecda35
MinIO Object Storage Server
Copyright: 2015-2025 MinIO, Inc.
License: GNU AGPLv3 - https://www.gnu.org/licenses/agpl-3.0.html
Version: RELEASE.2025-04-22T22-12-26Z (go1.24.2 linux/arm64)
API: http://172.18.0.2:9000 http://127.0.0.1:9000
WebUI: http://172.18.0.2:9001 http://127.0.0.1:9001
Docs: https://docs.min.io
WARN: Detected default credentials 'minioadmin:minioadmin', we recommend that you change these values with 'MINIO_ROOT_USER' and 'MINIO_ROOT_PASSWORD' environment variables
warningとして以下が表示されています。
WARN: Detected default credentials 'minioadmin:minioadmin', we recommend that you change these values with 'MINIO_ROOT_USER' and 'MINIO_ROOT_PASSWORD' environment variables
これはデフォルトのアクセスキーとシークレットキーを設定されているためアラートが表示されているものとなるので必要に応じて変更を行ってください。
今回はローカルでテスト利用のためそのまま続行とします。
MinIOの管理画面確認
ログを確認すると以下が表示されていますね。
WebUI: http://172.18.0.2:9001 http://127.0.0.1:9001
こちらはMinIOの管理画面にアクセスするためのURLが表示されているものとなるので、
ブラウザにhttp://127.0.0.1:9001
を打ち込んでみましょう。
MinIOの管理画面が表示されました。
次に「Username」「Password」にdocker-compose.ymlにて設定したMINIO_ROOT_USER
MINIO_ROOT_PASSWORD
の値を入力してログインしてみましょう。
今回はどちらもminioadmin
になります。
管理画面にログインできました。
今回のサンプルコードで作成したバケットやアップロードしたファイルはこちらからも確認することが可能です。
MinIOの接続確認ができたので次はサンプルコードで試していきましょう。
AWS SDK for Go v2 のインストール
S3互換APIを叩くためにAWS SDKを追加します。
$ go get github.com/aws/aws-sdk-go-v2
$ go get github.com/aws/aws-sdk-go-v2/config
$ go get github.com/aws/aws-sdk-go-v2/service/s3
※go.modファイルの作成がまだでしたら以下コマンドをサンプルに作成してください。
$ go mod init example.com
サンプルコード
package main
import (
"context"
"fmt"
"io"
"log"
"os"
"strings"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
const (
endpoint = "http://localhost:9000"
accessKeyID = "minioadmin"
secretAccessKey = "minioadmin"
bucketName = "test-bucket"
fileName = "sample.txt"
region = "ap-northeast-1"
)
func createS3Client() (*s3.Client, error) {
// 明示的にカスタムエンドポイントを指定
customResolver := aws.EndpointResolverFunc(func(service, region string) (aws.Endpoint, error) {
return aws.Endpoint{
URL: endpoint,
SigningRegion: region,
}, nil
})
cfg, err := config.LoadDefaultConfig(context.TODO(),
config.WithEndpointResolver(customResolver),
config.WithCredentialsProvider(
credentials.NewStaticCredentialsProvider(accessKeyID, secretAccessKey, ""),
),
)
if err != nil {
return nil, err
}
return s3.NewFromConfig(cfg, func(o *s3.Options) {
o.UsePathStyle = true // MinIOではPath-styleが必要
}), nil
}
func main() {
client, _ := createS3Client()
ctx := context.TODO()
bucket := bucketName
// 1. バケット作成 (既存ならスキップ)
_, err := client.CreateBucket(ctx, &s3.CreateBucketInput{
Bucket: &bucket,
})
if err != nil {
if strings.Contains(err.Error(), "BucketAlreadyOwnedByYou") {
fmt.Println("ℹ️ 既にバケットが存在しています:", bucket)
} else {
log.Fatalf("バケット作成失敗: %v", err)
}
} else {
fmt.Println("✅ バケット作成:", bucket)
}
// 2. ファイルアップロード
file, err := os.Open("./upload/" + fileName)
if err != nil {
log.Fatalf("ファイルオープン失敗: %v", err)
}
defer file.Close()
_, err = client.PutObject(ctx, &s3.PutObjectInput{
Bucket: &bucket,
Key: aws.String(fileName),
Body: file,
})
if err != nil {
log.Fatalf("アップロード失敗: %v", err)
}
fmt.Println("✅ sample.txt をアップロードしました")
// 3. ファイルダウンロード
out, err := client.GetObject(ctx, &s3.GetObjectInput{
Bucket: &bucket,
Key: aws.String(fileName),
})
if err != nil {
log.Fatalf("ダウンロード失敗: %v", err)
}
defer out.Body.Close()
local, _ := os.Create("./download/" + "download.txt")
defer local.Close()
io.Copy(local, out.Body)
fmt.Println("✅ download.txt を作成しました")
}
uploadディレクトリにMinIOにアップロードするサンプルテキストを作成します。
$ touch ./upload/sample.txt
作成されたファイルを開き任意の文字列を書き込みます。
Hello MinIO!
コマンド実行
main.goのファイルがあるディレクトリにて以下コマンドで実行してみましょう。
$ go run main.go
実行結果
✅ バケット作成: test-bucket
✅ sample.txt をアップロードしました
✅ download.txt を作成しました
無事に実行が完了しバケットの作成、及びファイルのアップロード、ダウンロードができているか確認してみましょう。
アップロード確認
管理画面をブラウザにて確認することでバケットの作成及び、ファイルのアップロードができていることが確認できます。
ダウンロード確認
downloadファイル配下にダウンロードされたファイルが格納されていることがわかります。
$ ls download/
download.txt
$ cat download/download.txt
Hello MinIO!
コンテナ停止・削除
開発が終わったら、downコマンドでMinIOコンテナを停止しておきましょう。
$ cd docker
$ docker compose down
まとめ
MinIOは簡単にローカルでS3モック環境を構築でき、
AWS SDK for Go v2 と組み合わせることで、既存のS3コードをそのまま流用可能です。
テストやローカル開発時の依存を減らし、CIにも組み込みやすいものとなります。
MinIOでS3をモックして自由にテストを行いましょう。
以上、参考になれば幸いです。
ありがとうございました。