初めてDockerに.envを導入するときに読む記事

# はじめに

私は今年で新卒入社２年目都内のIT企業で働いています。
入社してまだ浅いので、Dockerはある程度使えるものの、詳しいところまではわからず。また、.envと環境変数という存在は知っているものの使い方が良くわからずにいました。

そんな中、AWS SDK for Pythonを利用することになり、AWSのアクセスキーIDとシークレットアクセスキーをDockerの環境変数に設定することになりました。

(経緯については[こちら](https://qiita.com/Sicut_study/items/3a4a0f107462a8d9487a)を確認ください)

そこで、最初に行っていたのが、`Dockerfile`に環境変数をそのまま書くことでした。


```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`に以下のように記述しました。

```.env
AWS_ACCESS_KEY_ID=<アクセスキーID>
AWS_SECRET_ACCESS_KEY=<シークレットアクセスキー>
```

これで、Docker内では、AWS_ACCESS_KEY_IDでアクセスキーが取得できるようになります。

ちなみに、このような記述をするとエラーになります。

```.env
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の設定

環境変数を実際にコンテナに設定していきます。

```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`はエラーが発生します。

```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のように習慣的に`-`を記述していましたが、`-`を環境変数のところに記述すると`配列`として認識されるようでエラーが出てしまします。

詳しくは[こちら](https://qiita.com/rinasan3/items/68ffa55a9cfaef27da6b)をご覧ください。

## 2. 環境変数の書き方が違うのでエラー

```docker-compse.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
```

このように`- "TZ=Asia/Tokyo"のような環境変数の表し方を入れてしまうと以下のようなエラーになりました。

```docker-compose.yml
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`に以下を記述します。(初期で記述されていることもあります)

```.gitignore
.env
```

この短いコードで無視されるようになります。

これで、Pushしても安全です。

また、環境変数をどのように設定するかGitからcloneした人はわからないので、`.env_template`というファイルを作成しておくと分かりやすいです。

```
┣ Dockerfile
┣ docker-compose.yml
┣ .env
┣ .gitignore
┣ .env_template
```

`.env_template`は以下のように書きました。

```.env_template
AWS_ACCESS_KEY_ID=<アクセスキーID>
AWS_SECRET_ACCESS_KEY=<シークレットアクセスキー>
```

Gitからローカルに持ってきた際には、`.env`のファイルを作成して、`.env_template`の内容をコピーして、<>の部分を自分のキーに変更します。

また、README.mdにやり方を書くと親切です。

```Readme.md
# AWS SDKを利用する場合
1. `.env`というファイルを作成する
2. `.env_template`の内容をコピーして.envに貼り付ける
3. 自分のアクセスキーIDとシークレットアクセスキーを該当の箇所に記述する
```


# おわりに

Dockerの.envと環境変数の扱い方についてまとめてみました。
Dockerを詳しいといえるようになりたいものです。

# 参考記事

https://qiita.com/Sicut_study/items/3a4a0f107462a8d9487a

https://qiita.com/rinasan3/items/68ffa55a9cfaef27da6b

https://qiita.com/rururu_kenken/items/972314402d588e073d40