4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Windows環境における docker-compose の .env と 環境変数の優先順位

Last updated at Posted at 2019-03-24

前提

ドキュメントによると、 .env で変数を指定した場合でも環境変数のほうが優先されると書いてある。

Values in the shell take precedence over those specified in the .env file.

Environment variables in Compose | Docker Documentation

実行時に環境変数を指定すると、常に .env ファイル中で定義した変数を上書きします。

環境ファイル — Docker-docs-ja 17.06.Beta ドキュメント

背景(不思議な挙動)

環境変数 http_proxy が設定されている状態で .envhttp_proxy を別の値で記述すると .env の値が優先された1

ドキュメントの記述と一致していないように感じたので調査した。

検証

環境

Windows 10 Home + docker-machine

$ docker.exe --version
Docker version 18.03.0-ce, build 0520e24302

$ docker-compose.exe --version
docker-compose version 1.20.1, build 5d8c71b2

$ docker-machine.exe --version
docker-machine.exe version 0.14.0, build 89b8332

$ docker-machine.exe ssh default docker --version
Docker version 18.09.1, build 4c52b90

docker-compose.yml

docker-compose.yml
version: '3'

services:
  test:
    image: alpine:3.9
    command: env
    environment:
      - AAA
      - BBB
      - CCC
      - DDD
      - EEE
      - fff
      - ggg
      - hhh
      - iii
      - jjj

.env

.env
AAA=.env_var
BBB=.env_var
CCC=.env_var
DDD=.env_var
EEE=.env_var

fff=.env_var
ggg=.env_var
hhh=.env_var
iii=.env_var
jjj=.env_var

環境変数

以下の4つを環境変数として設定

  • DDD
  • EEE
  • iii
  • jjj
$ env | sort | grep env_var
DDD=user_env_var
EEE=system_env_var
iii=user_env_var
jjj=system_env_var

※ Windows環境のため、ユーザー環境変数とシステム変数を大文字小文字それぞれ設定

test.sh

以下の変数を sh 内で定義2

  • シェル変数
    • AAA
    • fff
  • 環境変数 (export2)
    • BBB
    • ggg
test.sh
# !/bin/sh -x

cat .env

echo -e "\n\n"

printenv AAA
printenv BBB
printenv CCC
printenv DDD
printenv EEE

printenv fff
printenv ggg
printenv hhh
printenv iii
printenv jjj

echo -e "\n\n"

AAA=sh_var
export BBB=exported_sh_var

fff=sh_var
export ggg=exported_sh_var

echo -e "\n\n"

printenv AAA
printenv BBB
printenv CCC
printenv DDD
printenv EEE

printenv fff
printenv ggg
printenv hhh
printenv iii
printenv jjj

echo -e "\n\n"

docker-compose config
docker-compose up

実行結果

Git Bash で実行した。

$ ./test.sh
+ cat .env
AAA=.env_var
BBB=.env_var
CCC=.env_var
DDD=.env_var
EEE=.env_var

fff=.env_var
ggg=.env_var
hhh=.env_var
iii=.env_var
jjj=.env_var
+ echo -e '\n\n'



+ printenv AAA
+ printenv BBB
+ printenv CCC
+ printenv DDD
user_env_var
+ printenv EEE
system_env_var
+ printenv fff
+ printenv ggg
+ printenv hhh
+ printenv iii
user_env_var
+ printenv jjj
system_env_var
+ echo -e '\n\n'



+ AAA=sh_var
+ export BBB=exported_sh_var
+ BBB=exported_sh_var
+ fff=sh_var
+ export ggg=exported_sh_var
+ ggg=exported_sh_var
+ echo -e '\n\n'



+ printenv AAA
+ printenv BBB
exported_sh_var
+ printenv CCC
+ printenv DDD
user_env_var
+ printenv EEE
system_env_var
+ printenv fff
+ printenv ggg
exported_sh_var
+ printenv hhh
+ printenv iii
user_env_var
+ printenv jjj
system_env_var
+ echo -e '\n\n'



+ docker-compose config
services:
  test:
    command: env
    environment:
      AAA: .env_var
      BBB: exported_sh_var
      CCC: .env_var
      DDD: user_env_var
      EEE: system_env_var
      fff: .env_var
      ggg: .env_var
      hhh: .env_var
      iii: .env_var
      jjj: .env_var
    image: alpine:3.9
version: '3.0'

+ docker-compose up
Starting 1_test_1 ... done
Attaching to 1_test_1
test_1  | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
test_1  | HOSTNAME=02a7c6031232
test_1  | AAA=.env_var
test_1  | BBB=exported_sh_var
test_1  | CCC=.env_var
test_1  | DDD=user_env_var
test_1  | EEE=system_env_var
test_1  | fff=.env_var
test_1  | ggg=.env_var
test_1  | hhh=.env_var
test_1  | iii=.env_var
test_1  | jjj=.env_var
test_1  | HOME=/root
1_test_1 exited with code 0

fffjjj が全て .env が優先され、 .env で定義した .env_var になっている。

      fff: .env_var
      ggg: .env_var
      hhh: .env_var
      iii: .env_var
      jjj: .env_var

ちなみに、Linux環境では、 AAAEEE と同じように環境変数が優先される。

      fff: .env_var
      ggg: exported_sh_var
      hhh: .env_var
      iii: user_env_var
      jjj: system_env_var

おまけ

変数名に小文字・数字・記号が入る場合

  • 大文字・小文字(Xx): .env 優先(Linux環境では環境変数優先)
  • 大文字・数字(Y123): 環境変数優先
  • 大文字・記号(Z_Z): 環境変数優先

docker-compose.yml

version: '3'

services:
  test:
    image: alpine:3.9
    command: env
    environment:
      - Xx
      - Y123
      - Z_Z

.env

Xx=.env_var
Y123=.env_var
Z_Z=.env_var

test.sh

# !/bin/sh -x

cat .env

echo -e "\n\n"

export Xx=exported_sh_var
export Y123=exported_sh_var
export Z_Z=exported_sh_var

echo -e "\n\n"

printenv Xx
printenv Y123
printenv Z_Z

echo -e "\n\n"

docker-compose config
docker-compose up

実行結果

test.sh
$ ./test.sh
+ cat .env
Xx=.env_var
Y123=.env_var
Z_Z=.env_var
+ echo -e '\n\n'



+ export Xx=exported_sh_var
+ Xx=exported_sh_var
+ export Y123=exported_sh_var
+ Y123=exported_sh_var
+ export Z_Z=exported_sh_var
+ Z_Z=exported_sh_var
+ echo -e '\n\n'



+ printenv Xx
exported_sh_var
+ printenv Y123
exported_sh_var
+ printenv Z_Z
exported_sh_var
+ echo -e '\n\n'



+ docker-compose config
services:
  test:
    command: env
    environment:
      Xx: .env_var
      Y123: exported_sh_var
      Z_Z: exported_sh_var
    image: alpine:3.9
version: '3.0'

Linux環境での実行結果(抜粋)

      Xx: exported_sh_var
      Y123: exported_sh_var
      Z_Z: exported_sh_var

大文字環境変数でも強制的に上書きする

source ./.env を実行する

※ これだけLinux環境でも同じ挙動となった

docker-compose.yml

version: '3'

services:
  test:
    image: alpine:3.9
    command: env
    environment:
      - AAA
      - BBB
      - CCC

.env

AAA=.env_var
BBB=.env_var

test.sh

# !/bin/sh -x

export BBB=exported_sh_var
export CCC=exported_sh_var

echo -e "\n\n"

printenv AAA
printenv BBB
printenv CCC

echo -e "\n\n"

source ./.env

echo -e "\n\n"

printenv AAA
printenv BBB
printenv CCC

echo -e "\n\n"

docker-compose config
docker-compose up

実行結果

test.sh
$ ./test.sh
+ export BBB=exported_sh_var
+ BBB=exported_sh_var
+ export CCC=exported_sh_var
+ CCC=exported_sh_var
+ echo -e '\n\n'



+ printenv AAA
+ printenv BBB
exported_sh_var
+ printenv CCC
exported_sh_var
+ echo -e '\n\n'



+ source ./.env
++ AAA=.env_var
++ BBB=.env_var
+ echo -e '\n\n'



+ printenv AAA
+ printenv BBB
.env_var
+ printenv CCC
exported_sh_var
+ echo -e '\n\n'



+ docker-compose config
services:
  test:
    command: env
    environment:
      AAA: .env_var
      BBB: .env_var
      CCC: exported_sh_var
    image: alpine:3.9
version: '3.0'

コンテナ内に渡す環境変数だけ指定したいなら env_file

env_file: my.env のように docker-compose.yml に書くことで、 environment のように環境変数をコンテナに直接渡せる。

.env の定義は docker-compose.yml 内でも使えるため、完全な代替ではない

優先順位

  1. environment (環境変数)
  2. environment (.env)
  3. env_file

docker-compose.yml

version: '3'

services:
  test:
    image: alpine:3.9
    env_file: my.env
    command: env
    environment:
      - BBB
      - CCC

.env

AAA=.env_var
BBB=.env_var
CCC=.env_var

my.env

AAA=my.env_var
BBB=my.env_var
CCC=my.env_var

test.sh

# !/bin/sh -x

cat .env

echo -e "\n\n"

cat my.env

echo -e "\n\n"

printenv AAA
printenv BBB
printenv CCC

echo -e "\n\n"

export CCC=exported_sh_var

echo -e "\n\n"

printenv AAA
printenv BBB
printenv CCC

echo -e "\n\n"

docker-compose config

実行結果

test.sh
$ ./test.sh
+ cat .env
AAA=.env_var
BBB=.env_var
CCC=.env_var
+ echo -e '\n\n'



+ cat my.env
AAA=my.env_var
BBB=my.env_var
CCC=my.env_var
+ echo -e '\n\n'



+ printenv AAA
+ printenv BBB
+ printenv CCC
+ echo -e '\n\n'



+ export CCC=exported_sh_var
+ CCC=exported_sh_var
+ echo -e '\n\n'



+ printenv AAA
+ printenv BBB
+ printenv CCC
exported_sh_var
+ echo -e '\n\n'



+ docker-compose config
services:
  test:
    command: env
    environment:
      AAA: my.env_var
      BBB: .env_var
      CCC: exported_sh_var
    image: alpine:3.9
version: '3.0'

結論

Windows環境の場合、

  • 変数に
    • 小文字が含まれる場合は .env のほうが優先される
    • 小文字が含まれない場合(大文字・数字・記号のみの場合)は 環境変数 のほうが優先される
  • 小文字が含まれない変数も .env を優先させたい場合は source ./.env を実行することで環境変数の優先をキャンセルできる
    • env_file を使ったほうが自然&楽

Linux環境の場合、

  • 変数名中の小文字の有無によらず 環境変数 のほうが優先される
  • .env を優先させたい場合は source ./.env を実行することで環境変数の優先をキャンセルできる
    • env_file を使ったほうが自然&楽
  1. 一方、 環境変数 TZ.env で上書きされなかった。

  2. Git Bash で実行 2

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?