はじめに
私は今年で新卒入社2年目都内のIT企業で働いています。
入社してまだ浅いので、Dockerはある程度使えるものの、詳しいところまではわからず。また、.envと環境変数という存在は知っているものの使い方が良くわからずにいました。
そんな中、AWS SDK for Pythonを利用することになり、AWSのアクセスキーIDとシークレットアクセスキーをDockerの環境変数に設定することになりました。
(経緯についてはこちらを確認ください)
そこで、最初に行っていたのが、Dockerfile
に環境変数をそのまま書くことでした。
ENV AWS_ACCESS_KEY_ID <アクセスキーID>
ENV AWS_SECRET_ACCESS_KEY <シークレットアクセスキー>
この状態でGitにPushすると誰からも情報が丸見えになります。
そこで、今回は.env
を導入して、その問題を解決します。
ちなみに.envの存在はリポジトリをcloneした際に、先輩からやってと設定しましたが、何をしているかよくわかりませんでした。
また、.envの使い方がまとまっていて、すぐdocker-compose.yml
の対応のさせ方まで乗っている記事はすぐ見つけることができなかったため、まとめたいと思います。
.envの設定
.envを使うことで、docker内でアクセスキーなど重要な情報を直接書く必要がなくなります。また、変数のように扱えるので.envの内容を変更することですべてに反映することもできます。
今回の目的は、アクセスキーを直接書かないようにすることです。
.env
というファイル(名前はいらないです)をdocker-compose.ymlと同じ位置に作成しました。
┣ Dockerfile
┣ docker-compose.yml
┣ .env
.env
に以下のように記述しました。
AWS_ACCESS_KEY_ID=<アクセスキーID>
AWS_SECRET_ACCESS_KEY=<シークレットアクセスキー>
これで、Docker内では、AWS_ACCESS_KEY_IDでアクセスキーが取得できるようになります。
ちなみに、このような記述をするとエラーになります。
AWS_ACCESS_KEY_ID="SamplePasssword123"
エラーは以下の通りです。
services.notebook.environment contains {"AWS_ACCESS_KEY_ID": "\"SamplePassword123\""}, which is an invalid type, it should be a string
文字列を入力しますが、""を付けているせいで文字列として認識されていません。
以下が正しいです。
AWS_ACCESS_KEY_ID=SamplePasssword123
docker-compose.ymlの設定
環境変数を実際にコンテナに設定していきます。
version: '3'
services:
notebook:
build: ./libraries
environment:
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
AWS_DEFAULT_REGION: ap-northeast-1
AWS_DEFAULT_OUTPUT: json
TZ: Asia/Tokyo
volumes:
- ./:/home/jovyan/data/
ports:
- "80:8000"
networks:
- default
restart: always
networks:
default:
driver: bridg
最終的にはこのようになりました。
environment
に環境変数名と.envの環境変数名を記述するだけです。
これで、設定完了です。
また、以下のようなエラーがあり対処を行いましたので、記録として残しておきます。
1. 環境変数が配列として扱われたことによるエラー
以下のようdocker-compose.yml
はエラーが発生します。
version: '3'
services:
notebook:
build: ./libraries
environment:
- AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
(以下省略)
volumes:
- ./:/home/jovyan/data/
ports:
- "80:8000"
networks:
- default
restart: always
エラーは以下の通りです。
services.notebook.environment contains {"AWS_ACCESS_KEY_ID": "\"SamplePassword123\""}, which is an invalid type, it should be a string
実は先ほどみたエラーと同じで、文字列にしろと言っています。
問題は、-
を付けていたことでした。
volumesやportsのように習慣的に-
を記述していましたが、-
を環境変数のところに記述すると配列
として認識されるようでエラーが出てしまします。
詳しくはこちらをご覧ください。
2. 環境変数の書き方が違うのでエラー
version: '3'
services:
notebook:
build: ./libraries
environment:
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
AWS_DEFAULT_REGION: ap-northeast-1
AWS_DEFAULT_OUTPUT: json
- "TZ=Asia/Tokyo"
volumes:
- ./:/home/jovyan/data/
ports:
- "80:8000"
networks:
- default
restart: always
このように`- "TZ=Asia/Tokyo"のような環境変数の表し方を入れてしまうと以下のようなエラーになりました。
ERROR: yaml.parser.ParserError: while parsing a block collection
ですので、以下のように修正しましょう。
TZ: Asia/Tokyo
.gitignoreの設定
このままではGitにPushした段階で、.env
をみたら誰でもキーを知ることができてしまします。
ですので、.gitignore
に.env
をPushの対象外にする設定を書きます。
.gitignore
を作成します。
┣ Dockerfile
┣ docker-compose.yml
┣ .env
┣ .gitignore
そして、.gitignore
に以下を記述します。(初期で記述されていることもあります)
.env
この短いコードで無視されるようになります。
これで、Pushしても安全です。
また、環境変数をどのように設定するかGitからcloneした人はわからないので、.env_template
というファイルを作成しておくと分かりやすいです。
┣ Dockerfile
┣ docker-compose.yml
┣ .env
┣ .gitignore
┣ .env_template
.env_template
は以下のように書きました。
AWS_ACCESS_KEY_ID=<アクセスキーID>
AWS_SECRET_ACCESS_KEY=<シークレットアクセスキー>
Gitからローカルに持ってきた際には、.env
のファイルを作成して、.env_template
の内容をコピーして、<>の部分を自分のキーに変更します。
また、README.mdにやり方を書くと親切です。
# AWS SDKを利用する場合
1. `.env`というファイルを作成する
2. `.env_template`の内容をコピーして.envに貼り付ける
3. 自分のアクセスキーIDとシークレットアクセスキーを該当の箇所に記述する
おわりに
Dockerの.envと環境変数の扱い方についてまとめてみました。
Dockerを詳しいといえるようになりたいものです。
参考記事