プライベートな docker-registry を S3 + CloudFront で

Docker Hub のオープンソース版 docker-registry.

公開できない Docker Image をプライベートにホストするために使っています.

最終的には docker pull に対して Cloudfront から配信できるようになったんですが、リポジトリのドキュメント(ADVANCED.md)通りにやったらプチハマったので書く.

当時の docker-registry バージョンは 0.9.1.

まずは S3 だけで

これは簡単で、Quick start の通りにやれば一発で使えるようになりました.

IAM ロールとか作って S3 をセキュアにするあたりのほうがよっぽど面倒かも.

Cloudfront を使おうとしてハマる

そもそもプライベートなイメージを配信するために使ってるので、Signed URL を使う形で Cloudfront ディストリビューションを作り、S3 Storage with Cloudfront の通りに docker run.

ドキュメントによれば、うまいこと Cloudfront から配信されている場合には、302 リダイレクトされるとのこと.

docker logs でログを見てみたところ、リダイレクトされている気配なし…

困ったのでソースを読んだ.

ドキュメントの記載がちょっと足りてなかった

うまく Cloudfront から配信が有効になってなかった理由は、S3 Storage with Cloudfrontに描かれているコマンドに環境変数の指定が足りてなかったから.

Cloudfront サポートの実装プルリク をよーく見てみると storage_redirect が指定されており、たしかにソースでも storage_redirect が true かどうかで分岐していた.

ので、-e STORAGE_REDIRECT=true を足してあげれば OK.

docker run \
         -e SETTINGS_FLAVOR=cloudfronts3 \
         -e STORAGE_REDIRECT=true \ # コレ
         -e AWS_BUCKET=mybucket \
         -e STORAGE_PATH=/registry \
         -e AWS_KEY=myawskey \
         -e AWS_SECRET=myawssecret \
         -e SEARCH_BACKEND=sqlalchemy \
         -e AWS_SECURE=false \
         -e AWS_ENCRYPT=false \
         -e AWS_PORT=80 \
         -e AWS_DEBUG=true \
         -e CF_BASE_URL=cloudfront_url
         -e CF_KEYID=cloudfront_key_id
         -e CF_KEYSECRET=cloudfront_private_key
         -p 5000:5000 \
         registry

で、無事 302 リダイレクトされて Cloudfront から配信されるようになりました.

docker pull にかかる時間が減って仕事が捗りますね.

プルリク出したけどマージされるかなー…

2015.03.17 追記: 1日待たずにマージされた. 動きが速いプロジェクトっていいですね.