- 1. Dockerfile における環境変数の定義
- 2. 定義した環境変数へのアクセス
- 3. 環境変数を利用してイメージをビルドする例
- 注意点
- 環境変数に関する tips
- 参考記事:Docker で環境変数をホスト OS 側からゲスト OS 側(コンテナ)に渡す方法
Dockerfile における環境変数の定義とその周辺に関する tips をまとめた.参考は公式リファレンスの以下の部分.
1. Dockerfile における環境変数の定義
Dockerfile では,ENV
statement によりビルド時の環境変数を定義できる.ENV
により環境変数が定義されれば,その行以降のコマンドにおいて定義した環境変数にアクセスできるようになる.
また,Dockerfile 内で定義される環境変数は,ビルド時の環境変数,つまりビルドイメージにおける環境変数であり,コンテナ環境においてもその環境変数は持続される.イメージのビルド後,docker inspect
でそのイメージで定義されている環境変数を見ることができる.
ENV
による環境変数の定義
一度に定義できる環境変数の数は,空白区切りの場合 1 つ,=
を使う場合複数である.クオーテーション('
,"
)はエスケープされない場合除去される.
# 空白区切り ENV [variable-name] [value] # `=` を使用 ENV [variable-name]=[value] ENV [var1]=[value1] [var2]=[value2] ...
- 空白区切りの例
1 つ目のスペース(環境変数名の後のスペース)以降は全て value として扱われる(スペースも含めて).
# 2 つの myName は等価 ENV myName "John Doe" ENV myName John Doe # 2 つの myDog は等価 ENV myDog "Rex The Dog" ENV myDog Rex The Dog ENV myCat fluffy
=
を使う例
文字列にスペースを入れたい場合,スペースの前に \
(バックスラッシュ)を入れる必要がある(行末の \
は line-continuation 記号であるため注意).
# 2 つの myName は等価 ENV myName="John Doe" \ myName=John\ Doe # 2 つの myDog は等価 ENV myDog=Rex\ The\ Dog \ myDog="Rex The Dog" ENV myCat=fluffy
2. 定義した環境変数へのアクセス
定義した環境変数へのアクセス
$variable_name
${variable_name}
注意点
定義した環境変数へアクセスできる statement 一覧
ADD
COPY
ENV
EXPOSE
FROM
LABEL
STOPSIGNAL
USER
VOLUME
WORKDIR
ONBUILD
(when combined with one of the supported instructions above)
3. 環境変数を利用してイメージをビルドする例
簡単な例を以下に示す.'/bar'
という文字列を格納する環境変数 foo
を定義している(コメントは変数を展開したもの).
FROM busybox ENV foo /bar # 環境変数にアクセス WORKDIR ${foo} ADD . $foo COPY \$foo /quux # WORKDIR /bar # ADD . /bar # COPY $foo /quux エスケープ
注意点
環境変数の持続性による副作用
Dockerfile 内で定義した環境変数はコンテナ環境でも持続すると前述したが,これは思わぬ副作用を生み得る.例えば,ENV DEBIAN_FRONTEND noninteractive
が挙げられる.これは,Debian 系 OS におけるパッケージインストール時のインタラクティブ操作(確認ダイアログ)の非表示設定である.
環境変数による副作用を起こさないようにするには,
RUN <variable-name>=<value> <command>
により一時的な環境変数を利用するのが良い(参考:bashで環境変数をexportせずにシェルスクリプトを実行したい場合はコマンドの前に記述することで代替できる - コード日進月歩).これならばコンテナ環境の環境変数に反映されずにそのコマンド内で副作用が収まる.
ホスト(ローカル)の環境変数と Dockerfile の環境変数は異なる
基本事項の確認ではあるが,Dockerfile における「環境変数」とは,ビルド時(イメージ,コンテナ環境)の環境変数である.ホストの環境変数とは異なるものである.
例えば,Dockerfile 内でコマンドサーチパスの環境変数 $PATH
にアクセスした場合,(ローカルではなく)コンテナ環境での $PATH
にアクセスする.
環境変数に関する tips
Dockerfile の環境変数に関する tips をいくつか挙げた.
インストールしたソフトウェア,パッケージをコマンドサーチパスに追加
コマンドサーチパスは所謂「パスを通す」の「パス」のこと.RUN
でインストールしたソフトウェア,パッケージを使用する際,それをパスに追加していないと当然 command not found
エラーが起きる.この場合,RUN
を実行する前にパスを通しておく必要がある.
Dockerfile でパスを通すには ENV
を使う(RUN export PATH=$PATH:/usr/...
だと上手くいかないらしい).例えば,jruby を使用するためには以下のようにパスを通す必要がある.
# パスを通す ENV PATH $PATH:/usr/local/jruby/bin RUN jgem install hoge
Python で自作ライブラリにパスを通す
Python では,import [library]
によりソースコード中でライブラリを使えるようにするが,import
文の実行時には(シェルの PATH
のように)PYTHONPATH
という環境変数(Python パッケージのサーチパス)を参照しライブラリを探す.
pip
でインストールしたライブラリは PYTHONPATH
に含まれるディレクトリにデフォルトでインストールされるため問題ないが,自作ライブラリを import
する場合は自分で PYTHONPATH
にディレクトリを追加する必要がある.以下に例を示す.
- example
ローカルの src/lib/
からビルドイメージの /app/src/lib
へライブラリのディレクトリを追加し,そのディレクトリに PYTHONPATH
を通す.
ADD ./src/lib /app/src/lib ENV PYTHONPATH /app/src/lib
これを実行しておけば,コンテナ環境で sys.path.append
などを行わずに import [自作ライブラリ]
が実行できるようになる.
参考記事:Docker で環境変数をホスト OS 側からゲスト OS 側(コンテナ)に渡す方法
本記事とは趣旨が少し異なるが,いずれ必要になりそうなのでメモ.
Dockerfile に限らず,ホスト OS 側から Docker コンテナ内のアプリケーション,スクリプトに環境変数を渡す方法はいくつかある.渡したいものとしては,特定の API へのアクセストークン,SSH の鍵,各種パスワード?などを想定する.
以下の 5 つのコマンド,ファイルを経由してローカル環境からコンテナ環境へ環境変数を渡すことができる.詳細は参考記事を参照.
docker run
docker build
Dockerfile
ファイルdocker-compose run
docker-compose.yml
ファイル