Rails(API) + MySQL + Reactという構成でポートフォリオを作成する中で、ローカルで開発したものをコンテナに入れて動かす際に環境変数関係でハマりました。
原因は簡単なことでしたが、解決までかなりの時間がかかったため、その道のりを記録に残しておきます。
前提条件
・macOS Monterey v12.1
・ruby 3.0.3
・Rails 6.1.5
・MySQL 8.0.28
・Docker 20.10.12
・Docker Compose v2.2.3
やりたいこと
docker-compose.yml
で.env
に記載した環境変数を読み込みたい。
version: '3'
services:
db:
image: mysql:8.0.28
volumes:
- ./etc/my.cnf:/etc/mysql/conf.d/my.cnf
- hanger-talk_data:/var/lib/mysql
environment:
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
TZ: 'Asia/Tokyo'
...
env_file:
- ./api/.env
...
発生した問題
env_file
で.env
ファイルを指定しているのに、docker-compose.yml
で読み込めない。
$ docker-compose config
WARNING: The MYSQL_ROOT_PASSWORD variable is not set. Defaulting to a blank string.
...
environment:
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: '' <=ここ
TZ: Asia/Tokyo
環境変数が設定されていないと言われていますが、これを解決するのに結構な時間を要しました。
原因と解決法
原因
docker-compose.yml
と.env
ファイルが同じ階層に設置されていない。
rails-react-app
├── api
│ ├── ...
│ ├── config
│ │ ├── database.yml
│ │ └── ...
│ ├── ...
│ ├── .env <= ここ
│ └── ...
├── front
│ ├── ...
│ └── ...
├── ...
└── docker-compose.yml
docker-compose config
で、docker-compose.yml
が読み込んでいる環境変数を確認します。
$ docker-compose config
前述の通り、環境変数がセットされていないと言われました。
WARNING: The MYSQL_ROOT_PASSWORD variable is not set. Defaulting to a blank string.
解決法
docker-compose.yml
と.env
ファイルを同じ階層に置く。
rails-react-app
├── api
│ ├── ...
│ ├── config
│ │ ├── database.yml
│ │ └── ...
│ ├── ...
│ └── ...
├── front
│ ├── ...
│ └── ...
├── ...
├── .env <= ここ
└── docker-compose.yml
もう一度docker-compose config
をします。
$ docker-compose config
きちんと読み込まれていました。
$ docker-compose config
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: password <=ここ
TZ: Asia/Tokyo
それでも読み込めないときは?
データの永続性のためのDockerボリュームが変更前の状態を保持して悪さをすることがあります。これを一度削除して、再作成します。
まずは念の為コンテナを停止・削除。
$ docker-compose down
buildしたイメージを削除する。
$ docker rmi $(docker images -a -q) # すべてのイメージを削除するコマンド
ボリュームを削除する。
$ docker volume rm volume_name
再度ボリューム、イメージ、コンテナを構築する。
念の為ボリュームの設定を確認。
version: '3'
services:
db:
...
api:
...
front:
...
volumes:
my-app_data:
external: true
$ docker volume create --name my-app_data
$ docker-compose build
$ docker-compose up -d
参考:https://qiita.com/damele0n/items/ac20e93749eb060fddfa
Railsでも.env
ファイルを使いたい
Railsではお馴染みのgem 'dotenv-rails'
用に.env
を作りたいときは、docker-compose.yml
とは別に作ればOK。
rails-react-app
├── api
│ ├── ...
│ ├── config
│ │ ├── database.yml
│ │ └── ...
│ ├── ...
│ ├── .env <= ここ
│ └── ...
├── front
│ ├── ...
│ └── ...
├── ...
├── .env <= ここ
└── docker-compose.yml