LoginSignup
79

More than 1 year has passed since last update.

ローカルS3環境(minio)を構築する

Last updated at Posted at 2020-10-25

概要

ローカルでS3が使えるように環境を作る。
アプリなどから画像をS3に登録してサイト側で閲覧できるようにしたい。

お知らせ minIOのバージョンがアップされています。 この記事のminIOは1つ前のもの (RELEASE.2021-06-17T00-10-46Z) です。 ※ 最新のminIOの場合、異なる部分があると思うのでご注意ください

<参考サイト>
MinIOを使ってローカルで外部ストレージをAmazonS3から置き換える

ファイル構成

├ docker
│ └ minio
│   ├ config               ... minio設定 (git管理対象外)
│   ├ data                 ... minioデータ (git管理対象外) 
│   ├ export
│   │ └ static             ... 起動時に取り込むファイル
│   │   ├ 150x150.png
│   │   └ 640x480.png
│   └ policies
│     └ buckets
│        └ static
│           └ policy.json  ... staticバケットのポリシー定義
│
│.gitignore
├ docker-compose.yml
└ REAMDE.md

※ github: https://github.com/reflet/docker-s3

docker設定

minio9090 ポートで起動する設定となっています。
※ 起動時に docker/minio/export/... を取り込むように設定しています
※ 最新版は仕様が変わっているのでバージョン指定( RELEASE.2021-06-17T00-10-46Z )しています

docker-compose.yml
version: '3'
services:
  minio:
    image: minio/minio:RELEASE.2021-06-17T00-10-46Z
    container_name: 'minio'
    ports:
      - 9090:9000
    environment:
      - MINIO_ACCESS_KEY=minio
      - MINIO_SECRET_KEY=minio123
    entrypoint: sh
    command: -c "
      mkdir -p /data/.minio.sys/buckets;
      cp -r /policies/* /data/.minio.sys/;
      cp -r /export/* /data/;
      /usr/bin/minio server /data;
      "
    volumes:
      - ./docker/minio/data:/data
      - ./docker/minio/export:/export
      - ./docker/minio/config:/root/.minio
      - ./docker/minio/policies:/policies

Bucketのポリシー設定

static バケットのポリシー設定を記述します。

policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "*"
        ]
      },
      "Action": [
        "s3:GetBucketLocation",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::static"
      ]
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "*"
        ]
      },
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": [
        "arn:aws:s3:::static/*",
        "arn:aws:s3:::static"
      ]
    }
  ]
}

サーバ起動

下記コマンドにて、dockerコンテナを起動します。

$ docker-compose up -d

管理画面

minioの管理画面へアクセスできます。
※ ID、PASSは、 docker-compose.yml に記載されています。

$ open http://127.0.0.1:9090/

S3ファイルへアクセス

下記URLにて static バケットのファイルにアクセス可能です。
※ アプリなどからアクセスする際に指定するURLとなります

$ open http://127.0.0.1:9090/static/hoge.txt
$ open http://127.0.0.1:9090/static/150x150.png
$ open http://127.0.0.1:9090/static/640x480.png

hoge.png

150.png

640.png

AWS SDK for PHP

AWS SDK for PHP で使う場合は、以下のようにエンドポイントの指定が必要となります。
※ アクセス元が、docker内のコンテナか、docker外のホストかで「 endpoint 」が変わります

date_default_timezone_set('Asia/Tokyo');
require 'vendor/autoload.php';

$s3 = new Aws\S3\S3Client([
        'version' => 'latest',
        'region'  => 'ap-northeast-1',
        'credentials' => [
            'key'    => 'minio',
            'secret' => 'minio123',
        ],
        'endpoint' => 'http://minio:9000',        // ← 追加 (docker内からアクセス)
        // 'endpoint' => 'http://127.0.0.1:9090', // ← 追加 (ホストからアクセス)
        'use_path_style_endpoint' => true,        // ← 追加
]);

minioのファイル操作 (awscliコマンド)

管理画面から操作できますが、まとめて画像ファイルをアップしたいなどの場合、
aws-cliコマンドで操作した方が楽そうです。

$ aws --version

もし、コマンドが無い場合は追加する。

# MacOS
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
$ brew -v
$ brew install awscli
$ aws --version

# Ubuntu
$ sudo apt-get -y install unzip
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install
$ aws --version

Config設定

プロフィールを作成する。

$ aws configure --profile minio
AWS Access Key ID [None]: minio
AWS Secret Access Key [None]: minio123
Default region name [None]: ap-northeast-1
Default output format [None]: json

プロフィール一覧を確認してみる。

$ aws configure list-profiles

プロフィール(minio)の設定状況を確認してみる。

$ aws configure list --profile minio

バケット内のファイル一覧を確認する

# docker内からアクセス: --endpoint-url http://minio:9000
$ aws --profile minio --endpoint-url http://127.0.0.1:9090/ s3 ls s3://static
2020-10-25 09:33:53          5 hoge.txt

画像をまとめて転送する

media フォルダをまとめて static バケットに送る。

# docker内からアクセス: --endpoint-url http://minio:9000
$ aws --profile minio --endpoint-url http://127.0.0.1:9090/ s3 sync media s3://static/media

画像をまとめて削除する

media フォルダを削除する

# docker内からアクセス: --endpoint-url http://minio:9000
$ aws --profile minio --endpoint-url http://127.0.0.1:9090/ s3 rm s3://static/media/ --recursive

ファイルを追加する

# docker内からアクセス: --endpoint-url http://minio:9000
$ aws --profile minio --endpoint-url http://127.0.0.1:9090/ s3 cp fuga.txt s3://static
upload: ./hoge.txt to s3://static/fuga.txt

フォルダを追加する

# docker内からアクセス: --endpoint-url http://minio:9000
$ aws --profile minio --endpoint-url http://172.17.100.101:9090/ s3api put-object --bucket static --key hoge/ 

ファイルを削除する

# docker内からアクセス: --endpoint-url http://minio:9000
$ aws --profile minio --endpoint-url http://127.0.0.1:9090/ s3 rm s3://static/hoge.txt
delete: s3://static/hoge.txt

minioのファイル操作 (curlコマンド)

Linuxサーバであれば、ほぼ存在する「 curlコマンド 」で操作してみる。

ファイルを取得する

# docker内からアクセス: 127.0.0.1:9090 → http://minio:9000
$ curl http://127.0.0.1:9090/static/hoge.txt

ファイルを登録する (認証なし)

/tmp/hoge.txt 」を転送する例です。

# docker内からアクセス: http://127.0.0.1:9090 → http://minio:9000
$ export FILE='hoge.txt'
$ export URL='http://127.0.0.1:9090/static/${FILE}'
$ export PATH='/tmp/${FILE}'
$ curl -i --request PUT ${URL} \
  --upload-file ${PATH} \
  -H "x-amz-acl: bucket-owner-full-control"

ファイルを登録する (認証あり)

/tmp/hoge.txt 」を転送する例です。

# docker内からアクセス: http://127.0.0.1:9090 → http://minio:9000
export S3_KEY="minio"
export S3_SECRET="minio123"
export RESOURCE="/static/hoge.txt"
export CONTENT_TYPE="application/octet-stream"
export DATE=`date -R`
export _SIGNATURE="PUT\n\n${CONTENT_TYPE}\n${DATE}\n${RESOURCE}"
export SIGNATURE=`echo -en ${_SIGNATURE} | openssl sha1 -hmac ${S3_SECRET} -binary | base64`
curl -v -X PUT http://127.0.0.1:9090${RESOURCE} \
  -T /tmp/hoge.txt \
  -H "Host: 127.0.0.1:9090" \
  -H "Date: ${DATE}" \
  -H "Content-Type: ${CONTENT_TYPE}" \
  -H "Authorization: AWS ${S3_KEY}:${SIGNATURE}"

ファイルを登録する (認証なし - PHP)

PHPで curl_exec() 関数にて送信を試してみる。

$file = '/tmp/hoge.txt';
$fp   = fopen($file, 'rb');
$size = filesize($file);

// docker内からアクセス: http://127.0.0.1:9090 → http://minio:9000
$url = 'http://127.0.0.1:9090/static/' . basename($file);
$ch  = curl_init($url);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_INFILESIZE, $size);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['x-amz-acl: bucket-owner-full-control']);
$response = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);

// 結果を見てみる
var_dump($info, $response)

以上

参考サイト

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
79