今回はdocker-composeを使ってもう少し色々やってみます
例としてdockerでmkdocs + elasticsearchを起動し、mkdocsのテキストをelasticsearchから検索できるようにします
やることは2点
- docker-compose起動(環境変数経由でhost ipを渡す)
- Dockerfile内で環境変数を参照してアプリケーションからのAJAXリクエスト先のIPをhost ipに設定できるようにする
実際に公開するアプリケーションであればドメインとってそれを指定すればOKだと思います
開発とかで使う場合/etc/hosts
を編集しても対応できると思いますが、複数の環境で/etc/hosts
をいじるのもどうかと思ったので実現できる方法を探してみたところなんとかなったので備忘録を兼ねて残しておきます
環境変数を渡す
docker-composeで環境変数を用いる方法
docker-composeの設定ファイルで${}
という形で変数を受け取れます
- docker-compose.yml
environment: - ES_ENDPOINT=${HOST_IP}
という形に設定してDockerfileでES_ENDPOINT
を参照できるようにします
$ HOST_IP=`hostname -I | awk '{print $2}'` 192.168.100.12 $ HOST_IP=`hostname -I | awk '{print $2}'` docker-compose up
コマンドでHOST_IP
を渡します
shellscriptのようにデフォルト値を与えることが出来ないようなので環境変数を渡すのが必須にはなってしまうようです。。。
下記参照
Compose File Reference docs.docker.com
余談ですがリファレンスの日本語化プロジェクトもあるようです
Compose ファイル・リファレンス — Docker-docs-ja 1.12.RC ドキュメント http://docs.docker.jp/compose/compose-file.htmldocs.docker.jp
dockerコンテナ起動時の前処理(テンプレートレンダリング)
entrykitを使います
ほぼここに書いてある通りです
サーバ上にajaxリクエストを送る部分があるのでそのリクエスト先を環境変数から参照させて環境によって変更するために使います
まずDockerのコンテナ上にentrykitをインストールします
- Dockerfile
ENV ENTRYKIT_VERSION 0.4.0 RUN curl -LO https://github.com/progrium/entrykit/releases/download/v${ENTRYKIT_VERSION}/entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz && \ tar zxvf entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz && \ mv entrykit /bin/entrykit && \ chmod +x /bin/entrykit && \ entrykit --symlink
テンプレートを使って変数を差し込む箇所を記述します
- config.js.tmpl
define(function() { return { esEndpoint: "{{ var "ES_ENDPOINT" | default "localhost" }}" } });
ES_ENDPOINT
をdocker-compose.ymlから渡しているのでそれを参照させます
entrykitを用いて前処理を追加します
- Dockerfile
COPY config.js.tmpl /config.js.tmpl ENTRYPOINT [ \ "render", "/config.js", "--", \ "prehook", "cp /config.js /docs/sample/custom/js/config.js", "--", \ "bash", "/entrypoint.sh" \ ]
renderで/config.js
に配置してprehookでアプリケーションが読み込む場所に配置しています
これはVOLUMEで指定したディレクトリ以下にconfig.jsを直接配置するとコンテナ起動時にファイルが存在しない旨のエラーになったために行いました
render処理してからvolumeへのマウントが行われている...?
なのでprehook時に移動してあげるようにしました
まとめ
entrykitいいねって話になってしまいましたが便利だと思います
こういうパターンはよくありそうですし
prehook,render以外にも使えるコマンドがあるので機会があれば使ってみたいです
実際のコードはこちら