Docker Compose における Secrets の利用
Secrets というのは、パスワード、証明書、API キーといった種類のデータを扱うものであり、ネットワークを介して送信することが不適切であったり、Dockerfile 内やアプリケーションソースコード内に暗号化せずにそのまま保存することが不適切であるような、あらゆるデータを指します。
Docker Compose では機密情報を保存する先として環境変数を用いることなく、別の方法を提供しています。
パスワードや API キーを環境変数に設定すると、意図しない情報漏洩のリスクにさらされるからです。
サービスが機密情報にアクセスできるのは、トップレベルの services
内において secrets
属性によって明示的に許可された場合のみです。
環境変数は場合によっては全プロセスからの利用が可能であるため、アクセスをすべて追跡することは困難です。 また感知していないところで、エラーデバッグを行う際に出力されてしまうかもしれません。 Secrets を利用すれば、こういったリスクは軽減されます。
Secrets の利用
secret はコンテナー内部において /run/secrets/<secret_name>
内のファイルとしてマウントします。
secret をコンテナーに含めるには 2 つのステップを経ます。 まず Compose ファイル内のトップレベル項目の secret として secret を定義します。 そしてその secret を利用して secret の属性 を参照するサービスの定義を適切に設定します。 Compose において secret へのアクセス権限は、各サービスごとに扱われます。
アクセス権限に関する手法は他のものとは異なっているため、標準的なファイルシステム上の権限を介して、きめ細かなアクセス制御が可能です。
利用例
単純な例
以下の利用例では、フロントエンドサービスにおいて my_secret
という secret へのアクセス権が与えられています。
このコンテナーでは ./my_secret.txt
のファイル内容が /run/secrets/my_secret
に設定されます。
services:
myapp:
image: myapp:latest
secrets:
- my_secret
secrets:
my_secret:
file: ./my_secret.txt
応用的な例
services:
db:
image: mysql:latest
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_root_password
- db_password
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
secrets:
db_password:
file: db_password.txt
db_root_password:
file: db_root_password.txt
volumes:
db_data:
この応用的な利用例では以下のことが行われています。
- 各サービスにおける
secrets
属性として、所定コンテナー内に含めたい secret を定義しています。 - トップレベルの
secrets
セクションでは、変数db_password
およびdb_root_password
を定義して、file
によってそれらの値を提供するファイルを指定しています。 - 各コンテナーのデプロイを行うと、Docker が
/run/secrets/<secret_name>
の配下に一時的なファイルシステムを生成し、そこに指定の値を設定します。
メモ
上に示している
_FILE
環境変数は、Docker の公式イメージ mysql や postgres などにおいて慣例的に用いられているものです。
secret のビルド
以下の利用例では npm_token
という secret がビルド時に利用可能となるようにしています。
その値は環境変数 NPM_TOKEN
から取得されます。
services:
myapp:
build:
secrets:
- npm_token
context: .
secrets:
npm_token:
environment: NPM_TOKEN