Dockerfileでは、環境変数を使用して、Dockerイメージやコンテナの動作を柔軟に制御できます。
環境変数を適切に活用することで、構成の変更や異なる環境間での移植が容易になります。
本記事では、ENV命令とARG命令、さらにDockerシークレットの基本的な使い方について初心者向けに説明します。
Dockerfileで使う環境変数
1. 環境変数を設定する方法
ENV命令
ENV命令を使用して、Dockerイメージ内で使用する環境変数を定義できます。- 定義した変数は、Dockerfile内やコンテナ実行時に利用可能です。
使用例:
FROM ubuntu:20.04
# 環境変数を設定
ENV APP_HOME=/usr/src/app
ENV APP_PORT=8080
# 環境変数を使用
WORKDIR $APP_HOME
EXPOSE $APP_PORT
ビルド時の環境変数設定 (ARG命令と--build-arg)
ARG命令
ARG命令は、Dockerイメージのビルド時に使用される変数を定義します。- 定義した
ARG変数は、Dockerfileの中でのみ使用できます(コンテナ実行時には使用できません)。
使用例:
FROM node:16
# ビルド時引数を定義
ARG NODE_ENV=production
# 環境変数として設定
ENV NODE_ENV=$NODE_ENV
CMD ["npm", "start"]
--build-argオプション
docker buildコマンドの--build-argオプションを使用して、ビルド時に値を指定できます。- 指定しない場合、Dockerfile内の
ARG命令で設定されたデフォルト値が使用されます。
コマンド例:
docker build --build-arg NODE_ENV=development -t myapp .
環境変数の活用例
設定ファイルのパス指定
環境変数を利用して、設定ファイルのパスを動的に変更できます。
使用例:
ENV CONFIG_PATH=/etc/app/config.yaml
CMD ["myapp", "--config", "$CONFIG_PATH"]
ビルド時と実行時の分離
ビルド時にはARGを、実行時にはENVを使用して、設定を分離できます。
FROM python:3.9
# ビルド時引数
ARG APP_VERSION=1.0.0
# 環境変数
ENV APP_VERSION=$APP_VERSION
ENV APP_PORT=5000
CMD ["sh", "-c", "echo Running version $APP_VERSION on port $APP_PORT"]
コンテナ実行時に環境変数を渡す
docker runの-eオプション
コンテナを実行するときに、環境変数を外部から指定できます。
docker run -e "APP_PORT=3000" myapp
.envファイルの使用
.envファイルに環境変数をまとめて記述し、--env-fileオプションで読み込むことができます。
.envファイルの例:
APP_PORT=3000
APP_HOME=/usr/src/app
コマンド例:
docker run --env-file .env myapp
ベストプラクティス
デフォルト値の設定
- 環境変数にはデフォルト値を設定し、値が指定されていない場合の挙動を制御します。
ENV APP_PORT=8080
機密情報の管理
- APIキーやパスワードなどの機密情報を環境変数で管理する場合、
.envファイルやDockerシークレットを使用します。 .envファイルは.gitignoreに追加して、ソース管理に含めないようにします。
軽量な変数名の使用
- 短く、意味が明確な変数名を使うことで、管理が簡単になります。
ENVとARGの適切な使い分け
- ビルド時にのみ使用する値:
ARG - 実行時にも参照される値:
ENV
実用例
Dockerfile:
FROM python:3.9
# 環境変数の定義
ENV APP_NAME=myapp
ENV APP_PORT=5000
# ビルド引数
ARG BUILD_ENV=production
# 環境変数の利用
WORKDIR /usr/src/$APP_NAME
EXPOSE $APP_PORT
# スクリプト内で環境変数を参照
CMD ["sh", "-c", "echo Running in $BUILD_ENV mode on port $APP_PORT"]
ビルドと実行:
docker build --build-arg BUILD_ENV=development -t my-python-app .
docker run -e APP_PORT=8080 my-python-app
Dockerシークレット
Dockerシークレットは、機密情報(例: パスワード、APIキー、TLS証明書など)をDockerが暗号化して管理し、Dockerコンテナで利用できる仕組みです。
Dockerシークレットの特徴
- 安全な管理:
- シークレットはDockerが暗号化して管理し、適切なアクセス権を持つサービスやタスクにのみ提供されます。
- シークレットはコンテナのファイルシステムに一時的にマウントされ、永続的に保存されません。
- 運用効率の向上:
- シークレットの内容をコードやDockerイメージに含める必要がないため、運用が安全かつ効率的です。
- サービススコープの制限:
- Docker Swarmモードでは、シークレットを特定のサービスにのみ提供できます。
Dockerシークレットの使い方
シークレットの作成
シークレットを作成するには、docker secret createコマンドを使用します。
例:
echo "my-secret-password" | docker secret create my_password -
このコマンドでは、my-secret-passwordという文字列をmy_passwordという名前のシークレットとして登録します。
シークレットをサービスに追加
Docker Swarmモードで、シークレットをサービスに渡すには、--secretオプションを使用します。
例:
docker service create --name my_service --secret my_password nginx
- このコマンドで、
my_passwordというシークレットがmy_serviceに利用可能になります。
コンテナ内でのシークレットの利用
- シークレットは、コンテナ内で
/run/secrets/<シークレット名>というパスにマウントされます。 - シークレットをファイルとして読み取れます。
例:
cat /run/secrets/my_password
使用例: シークレットを使ったMySQLサービスの設定
- MySQLのパスワードをシークレットとして作成:
echo "securepassword" | docker secret create mysql_root_password -
- MySQLサービスを作成し、シークレットを渡す:
docker service create --name mysql \
--secret mysql_root_password \
-e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql_root_password \
mysql:5.7
- コンテナ内でのシークレットの確認:
- MySQLは、環境変数
MYSQL_ROOT_PASSWORD_FILEで指定したパスからパスワードを読み取ります。
Dockerシークレットの注意点
- Swarmモードでのみ利用可能:
- Dockerシークレットは、Swarmモードが有効な状態で使用できます。
スタンドアロンのDockerコンテナでは直接利用できません。
- Dockerシークレットは、Swarmモードが有効な状態で使用できます。
- ローカルマシンに保存しない:
- シークレットの内容をローカルマシンやバージョン管理システム(例: Git)に保存しないように注意してください。
- メモリ内でのみ保持:
- シークレットはコンテナのメモリ内でのみ保持され、ディスクに書き込まれることはありません。
- アクセス制御:
- シークレットはサービス単位で管理され、意図しないサービスがアクセスできないように保護されています。
Dockerシークレットの利点
- セキュリティ強化: シークレットは暗号化され、意図しない漏洩を防ぐ。
- 分離性: アプリケーションコードやイメージから機密情報を分離できる。
- 簡単な統合: 既存のDocker Swarmワークフローに簡単に統合可能。
まとめ
Dockerfileで環境変数を使うことで、柔軟性と再利用性が向上します。ENV命令とARG命令を適切に使い分けることで、開発や運用の効率がさらに高まります。
特に設定ファイルやポート番号などを環境変数で管理することで、異なる環境間での移植性が向上します。

