- Floci 起動後に手動で s3 バケット や dynamodb テーブル を作っている
- 一次的なawsリソース作成スクリプトを実行するコンテナを、compose でサービス定義している
本記事はそんなあなたにおすすめ。
Flociには Initialization Hooks という機能が用意されています。
Floci について
今めちゃめちゃあついですよね。
awsのリソースをエミュレーション出来る感じです。
やりたいこと
冒頭でも言いましたが以下のようなことやりたくないですか?
「FlociでS3リソースをエミュレーションしたい。コンテナ起動直後バケットを作成しておきたい。」
また、以下のような「思い」や「悩み」を抱えられている方、いらっしゃいませんか?
- 「手動で aws cli を叩いてバケットを作成してました。ちょっとめんどくさいんですよね。」
- 「
s3-initサービスみたいなの作ってます...。リソースの初期化を行う一次的なコンテナを compose に定義して、バケット作成を自動化してました。でもなんか気持ち悪さは感じてて...。」
それでは、Flociが用意している機能を活用してそんな方々の思いを実現したいと思います。
Flociの Initialization Hooks 機能について
Floci allows you to execute custom shell scripts when it starts and stops.
要約すると、起動時とシャットダウン時にカスタムスクリプトを実行させることが出来るって感じです。
「処理が走るタイミング等」の細かい仕様は公式ドキュメントを参照下さい。
かなり充実してます。
なにが出来るかといいますと、先程の「やりたいこと」が出来ます。
方法
海外の方の記事をちらほら見ましたが、 docker-compose のボリューム指定をしている方法が多かったです。
本記事では、composeに頼らない方法を紹介しようと思います。
具体的には、「カスタムスクリプトを焼き込んだイメージを生成」「コンテナ起動すると該当のスクリプトが実行される」といった Floci コンテナの作成方法ですね。
「別にこだわりないよ。compose.yml で書けるならそれでいいんだよ。」という方はこちらを参考にしてね
#!/bin/sh
set -eu
: "${BUCKET_NAME:?BUCKET_NAME is required}"
aws --endpoint-url http://localhost:4566 \
s3api head-bucket \
--bucket "$BUCKET_NAME" >/dev/null 2>&1 ||
aws --endpoint-url http://localhost:4566 \
s3 mb "s3://$BUCKET_NAME"
services:
floci:
image: hectorvent/floci:latest
ports:
- "4566:4566"
volumes:
- ./data:/app/data
- ./init/start.d:/etc/floci/init/start.d:ro # ホストのボリュームを指定
あとは、以下を実行するだけ。
docker compose up floci
Dockerfileに閉じ込めるべき理由について
- ポータビリティ: docker-compose.yml とスクリプトファイルをセットで持ち運ぶ必要がなく、イメージ1つで完結する。
- CI/CDとの親和性: CI上のテストで aws s3 mb を実行するステップを減らせる。
- 一貫性: チームメンバー全員が、確実に「バケット作成済み」の環境を即座に立ち上げられる。
まぁ、「docker pullひとつで揃う」じゃないとコンテナ使う意味薄くなりますもんね。
composeはあくまでパラメータと他コンテナとの連携の場ってイメージ。
それでは作業しましょう。
1. スクリプトの用意
以下、スクリプトコードです。とりあえず aws cli でバケットを作っているだけです。
※ バケット名は環境変数から読み込んでます。
※ なにやってるか分かんない場合は help コマンドを使って仕様を読んでみてね。
#!/bin/sh
set -eu
: "${BUCKET_NAME:?BUCKET_NAME is required}"
aws --endpoint-url http://localhost:4566 \
s3api head-bucket \
--bucket "$BUCKET_NAME" >/dev/null 2>&1 ||
aws --endpoint-url http://localhost:4566 \
s3 mb "s3://$BUCKET_NAME"
2. イメージの作成
では、Dockerfileを書きましょう。
ベースイメージは hectorvent/floci:latest-awsでお願いします。
hectorvent/floci:latestだとだめな理由があって、aws コマンドが利用出来ないんですよね。
今回のように「イメージをカスタマイズしたい人向け」にネイティブのイメージに加えて、他に2つが用意されているようです。
-
hectorvent/floci:latest
native image (minimal, no apk) -
hectorvent/floci:latest-jvm
JVM image (Alpine-based, has apk) -
hectorvent/floci:latest-aws
JVM image with AWS CLI pre-installed
いろいろやりたい人は、apkが使える JVMイメージがおすすめ。今回は、aws cliが使えればいいので、3つ目のやつを使いましょう。
ちょっと脱線しましたが。
では、Dockerfileを以下のように定義します。
FROM hectorvent/floci:latest-aws
COPY init/01.sh /etc/floci/init/start.d/01.sh
# ヘルスチェック
HEALTHCHECK --interval=5s --timeout=5s --retries=12 \
CMD aws --endpoint-url http://localhost:4566 s3api head-bucket --bucket "$${BUCKET_NAME}" >/dev/null 2>&1
ここまで来たら docker buildするだけ。イメージをpushしてしまえば社内で配ったり、CIで使ったり出来ますね。
めちゃ簡単。
composeであえてやらない理由っていろいろありますけど、この辺りが強いですよね。
レシピに閉じ込めれる感じ。
あと、Flociのヘルスチェック指定ってリソースの死活管理がやりたいことに繋がりますよね。
今回の場合は特にヘルスチェックについてもDockerfileに閉じ込めるべきかと。
3. コンテナ起動
起動についてはお好みの方法でどうぞ。
docker run
docker run -d -p 4566:4566 --name floci-test my-floci-image
compose管理をしている場合
services:
floci:
build:
context: ./build/floci
dockerfile: Dockerfile
ports:
- "${FLOCI_PORT}:4566"
environment:
BUCKET_NAME: "qiita-app-bucket"
AWS_ACCESS_KEY_ID: test
AWS_SECRET_ACCESS_KEY: test
AWS_DEFAULT_REGION: ap-northeast-1
volumes:
- ./data:/app/data
docker compose up -d floci
ポートを環境変数で動的にしたい方へ
以下、どうぞ。
まとめ
Floci、めちゃくちゃいいですよね。今かなりホットです。
成長が目まぐるしいリポジトリですので、イメージのバージョン指定は latest版 ではなくちゃんとバージョンを明示してウォッチしやすくしておくのが良いと思います。