minioをVirtual Hosted Styleで利用する
はじめに
皆さんこんにちは。Linc'wellでバックエンド基盤チームを担当している山本です。私達のチームの役割のひとつとして以下が存在します。
「俯瞰した視座で言語、フレームワーク、ミドルウェアの効率的な利用の模索・情報提供を行い、プロダクトチーム内の能力ギャップを埋めることで少ない学習コストで開発の品質・速度を加速させる。」
今回取り上げるminioはAWS S3の環境をローカル開発環境でエミュレートする用途で広くRails開発者の間で使われています。このブログはminioをより本物のS3に近づけるためVirtual Hosted Styleに切り替え、プロダクト開発チームに貢献したお話を書きます。
Virtual Hosted Styleって何?
Amazon S3サービスは2006年にAWSのサービスの一部として産声を上げました。当初は以下のようにドメイン名は固定でパスによりファイルを指定する形式でした。この形式をPath Styleと呼びます。
https://s3.amazonaws.com/my-bucket/images/happy.jpeg
しかし多くのオブジェクトがS3上に格納されるようになり、DNSによる名前解決を行うことで、より高パフォーマンスに処理する必要が出てきたため2010年頃には以下のようにドメイン名にバケット名を含めるVirtual Hosted Styleが利用可能となりました。
https://my-bucket.amazonaws.com/images/happy.jpeg
2019年にはAmazon S3 path-style 廃止予定 – それから先の話 –というタイトルの公式ブログが公開され、段階的にPath Styleが廃止されることが告知されました。
私達が本番環境でS3を使う上で、もはやPath Styleは意識する必要はなくなったわけですね。
一般的なminioの設定
minioを使ってAWS S3をRails上でエミュレートする際に多くの場合 force_path_style
を指定されているものと思われます。
# config/initializers/minio.rb の設定例
if Rails.env.development? || Rails.env.test?
Aws.config.update(
endpoint: 'http://minio:9000',
region: 'ap-northeast-1'
)
Aws.config[:s3] = { force_path_style: true }
end
force_path_styleは古いURLの形式を強制的に指定する設定です。
これはローカル開発環境でバケット名をサブドメインに含めることが困難であることが理由です。
では、ここからminioをVirtual Hosted Styleに対応する方法を見ていきましょう。
Virtual Hosted Styleで名前解決する方法
Step1. ブラウザからコンテナへの名前解決
nip.io というWebサービスを利用することで、サブドメインを指定したURLをローカルホストに向けることができます。nip.ioについて、いくつか実験してみましょう。
- 127.0.0.1.nip.io
% dig 127.0.0.1.nip.io
; <<>> DiG 9.10.6 <<>> 127.0.0.1.nip.io
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55992
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;127.0.0.1.nip.io. IN A
;; ANSWER SECTION:
127.0.0.1.nip.io. 18720 IN A 127.0.0.1
;; Query time: 25 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Tue Nov 26 17:29:41 JST 2024
;; MSG SIZE rcvd: 61
- my-bucket.minio.127.0.0.1.nip.io
% % dig my-bucket.minio.127.0.0.1.nip.io
; <<>> DiG 9.10.6 <<>> my-bucket.minio.127.0.0.1.nip.io
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15122
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;my-bucket.minio.127.0.0.1.nip.io. IN A
;; ANSWER SECTION:
my-bucket.minio.127.0.0.1.nip.io. 21600 IN A 127.0.0.1
;; Query time: 391 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Tue Nov 26 17:30:44 JST 2024
;; MSG SIZE rcvd: 77
このように「(任意のサブドメイン).(IPアドレス).nip.io」と指定することで127.0.0.1というループバックアドレス(localhost)を返してくれます。
Step2. minioの設定変更
開発環境のminioの設定から force_path_style
を除去して、Endpoint URLを変更します。
# config/initializers/minio.rb の設定例
if Rails.env.development? || Rails.env.test?
Aws.config.update(
endpoint: 'http://minio.127.0.0.1.nip.io:9000', # 変更
region: 'ap-northeast-1'
)
# Aws.config[:s3] = { force_path_style: true } 除去
end
次に環境変数 MINIO_DOMAIN
を設定します。
# docker-compose.yml
services:
minio:
environment:
- MINIO_ROOT_USER=minio
- MINIO_ROOT_PASSWORD=password
- MINIO_DOMAIN=minio.127.0.0.1.nip.io # 追加
(略)
こうすることでminioはVirtual Hosted Styleで動作します。
Step3. コンテナ間の名前解決
次は開発コンテナ間の名前解決です。docker composeで開発環境を構築している場合、webコンテナ(Rails環境)からminioへは http://minio:9000
でアクセスできます。
しかし、Virtual Hosted Styleを利用すると、バケットのURLにサブドメインが含まれ、デフォルトのdocker composeの名前解決を利用することができません。
この問題に対して以下のようにdocker composeのネットワークエイリアスを設定します。
# docker-compose.yml
services:
minio:
environment:
- MINIO_ROOT_USER=minio
- MINIO_ROOT_PASSWORD=password
- MINIO_DOMAIN=minio.127.0.0.1.nip.io
networks:
default:
aliases:
- my-bucket.minio.127.0.0.1.nip.io # 追加
(略)
これにより、dockerコンテナ間でサブドメインを使ったminioへのアクセスができるようになりました。
ただ、この方法にも課題は存在しています。それは利用するバケットが増えるごとにネットワークエイリアスの設定を追加する必要がある点です。ホストマシンの /etc/hosts
に定義する方法もありますが、開発環境がコンテナ内で完結するだけマシという判断を行いました。
まとめ
nip.ioとdocker composeのネットワークエイリアスを利用することで本番環境と同じバケット指定URLが指定できるようになりました。現状はPath Styleでも問題ないとはいえ、今後の開発環境の進化に対応するためVirtual Hosted Styleに切り替えることは重要だと考えています。
皆さんも開発環境のVirtual Hosted Styleへの移行を検討してみてください。
Discussion