🐳

Docker Composeで環境変数のエイリアスを作りたい

2022/08/23に公開

経緯

相変わらずDocker上のMySQLをいじっている。

MySQLサーバに対して、毎回コンテナに入ってmysqlプロンプトを出してコマンドを打つのがめんどくさいので、webベースのGUIサーバを追加することにした。
このとき、.envで指定しているMySQL用のユーザ情報について、同じ値を別の名前で環境変数として指定する必要があった。

環境

docker-composeファイルは以下の通り。

version: '3.8'

services:
  db:
    container_name: db
    image: mysql:8.0
    environment:
      - LANG=ja_JP.UTF-8
    tty: true
    volumes:
      - type: volume
        source: test_volume
        target: /var/lib/mysql
    networks:
      - test_network

volumes:
  test_volume:
    name: test_volume

networks:
  test_network:
    external: true

.envはこの内容。

MYSQL_DATABASE=test_database
MYSQL_USER=test_user
MYSQL_PASSWORD=password
MYSQL_ROOT_PASSWORD=root_password

課題

今の環境に、phpmyadminというMySQLのGUIツールを新しいサービスとして導入する。
具体的に以下の内容を追加したい。

  db-gui:
    container_name: db-gui
    image: phpmyadmin/phpmyadmin
    environment:
      - LANG=ja_JP.UTF-8
    tty: true
    ports:
      - 8080:80
    depends_on:
      - db
    networks:
      - test_network

このとき、phpmyadminコンテナには環境変数PMA_HOSTS, PMA_USER, PMA_PASSWORDを渡して接続先と認証の情報を教える必要がある。
しかし、PMA_HOSTSはサービス名(db)を直書きすれば良いとして(networkが設定されてるので、サービス名←→アドレスができる)、他の2つの値は.envMYSQL_USER, MYSQL_PASSWORDと同一である。

愚直な方法として、.envPMA_USER, PMA_PASSWORDを追加しても良い。
が、同じ値(しかも認証情報!)を2回書くのはメンテナンス性も悪いし、ミスを誘発しやすい。

解決方法

今回、環境変数にエイリアスを設定することでこの問題を解決した。

このように、db-guiサービスのパラメータにenvironment:を設定して、値を${envで設定された変数名}とすることで、db-guiで変数が読まれる際にはMYSQL_USERの値で置き換えられる。

    environment:
      - LANG=ja_JP.UTF-8
      - PMA_ARBITRARY=1
      - PMA_HOSTS=db
      - PMA_USER=${MYSQL_USER}
      - PMA_PASSWORD=${MYSQL_PASSWORD}

おまけ

環境変数の評価タイミング的に、environment設定時に展開されるのか、参照時に展開されているのかが気になったので確認してみた。
つまり、PMA_USER="${MYSQL_USER}"なのか、PMA_USER="test_user"かということである。

試すのは簡単で、

docker compose exec db-gui bash
> echo $PMA_USER
test_user
> MYSQL_USER=hoge
> echo $PMA_USER
test_user

上書き後の最後の結果がtest_userなので、environmentに設定した変数はコンテナ作成時に評価されることが分かる。
更に複数の手段で指定される環境変数が、どの順番で読み込まれるかも分かる。
例えば、.envTEST=$PMA_HOSTSなどとenvironmentで指定された変数を利用しようとしても、デフォルト値の""として評価される。

一応確認してみるとこのようになる。

docker compose exec db-gui bash
> echo $TEST

> echo $PMA_HOSTS
db

逆に応用テクとしてこんな風に.envの内容を利用して複雑な変数を用意することもできたりする。

COMPLEX=${MYSQL_PASSWORD}concat_ENVS${MYSQL_PASSWORD}hogehuga
GitHubで編集を提案

Discussion