zaki work log

作業ログやら生活ログやらなんやら

Docker Compose実行時の環境変数の利用まとめ

大まかには把握してたし今更感はあるけれど、最近見つけたenv_fileは紛らわしかったので整理した。
なお実行時(コンテナデプロイ時)のときのみで、ビルドはまた別。

Composeファイルの定義でホストOSの環境変数を参照する

よくある使い方は、Composeファイルの定義内で環境変数を参照するようにテンプレート的に記載するもの。

基本形

${IMAGE_TAG}と記述すればイメージのタグを環境変数$IMAGE_TAGから参照できる。
また、以下のように${IMAGE_TAG:-latest}と記述すれば、環境変数$IMAGE_TAGが未定義の場合はlatestを使用するようにできる。

services:

  server:
    image: "docker.io/debian:${IMAGE_TAG:-latest}"

.envファイルを使ったホスト環境変数のセット

docker compose up実行時の環境変数は、実行ホストのシステムやシェルなどに設定された環境変数だけでなく、以下のような内容でプロジェクトディレクトリにある.envに書かれた環境変数も使用される。

IMAGE_TAG=stable-slim

なお、.envdocker compose実行環境の(シェルとかの)環境変数の両方に定義があれば、シェルの環境変数が優先される。

以下の記述でもOK

IMAGE_TAG: stable-slim

任意の外部ファイル定義をホストの環境変数としてセット

--env-fileオプションを使用する。
注意点としてcomposeサブコマンドの後に指定する。upの後だと認識しない。

$ docker compose up -d --env-file .custom_env
unknown flag: --env-file

$ docker compose --env-file .custom_env up -d
WARN[0000] No services to build
[+] up 2/2
 ✔ Network env-value_default Created
 ✔ Container env-value-app-1 Created

.custom_envの書式は.envファイルと同様。

デプロイするコンテナ内の環境変数を設定する

コンテナ内で実行するアプリケーションで利用したい環境変数を定義するパターン。

composeファイルで定義

environmentを使用する。
これはPostgreSQLコンテナでDBの初期設定を投入するなど、よくある使い方。

  db:
    image: postgres
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: curry_tabetai
      POSTGRES_DB: sample

外部ファイル定義

前述の--env-fileコマンドラインオプションと名前・動作が紛らわしいけど、env_fileを使用する。
env_fileで指定したファイル内の環境変数定義は、コンテナ内で使用できる。
Git管理するであろうcomposeファイルへの記述が難しいトークン系情報などを、外部ファイル経由で環境変数としてセットできる。

  db:
    image: postgres
    env_file:
    - .db_initialize

.db_initializeの中身は以下の通り。

POSTGRES_USER=admin
POSTGRES_PASSWORD=curry_tabetai
POSTGRES_DB=sample

ホストOSの環境変数をコンテナ内でも使用するには

逆に言うとコンテナ内で使用する環境変数を、ホストOSの環境変数から注入したい場合。(たとえば機密性の高いトークン情報なのでcomposeファイルは論外、外部ファイルにも書き出したくないとか)

原則としてコンテナの環境変数はホストOSの環境変数とは独立しているので、渡したい環境変数は個別にenvironmentなどで定義する。

  db:
    image: postgres
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}

おまけ: composeファイル内でコンテナの環境変数を参照する

$が1つだとホストOSの環境変数を参照・展開してしまうので、コンテナ内で$を解釈するために二重に記述。その上でshellのコマンド実行の場合はsh -c$を解釈させてやる。

    environment:
      VALUE: hello
    command: sh -c 'echo "$$VALUE"'

docs.docker.com


Ansibleの環境変数も実行元と実行先で考える必要あったりややこしいけど、コンテナもこれに加えてビルドの話もあるのでやっぱややこしい。

zaki-hmkc.hatenablog.com

参考

だいたい全部ここに載ってる。

docs.docker.com