今回達成すること
docker-compose.ymlファイルを編集する前に、Dockerでの環境変数の扱い方ついて理解します。
今回作るアプリケーションの環境変数設計
環境変数とは何か?
環境変数とは、開発・テスト・本番などの環境ごとに変化する値を入れる変数となります。
代表的な例は、URLですね。
同じアプリを動かすにしても開発の場合「http://localhost:3000」、本番の場合「https://xxx.com」のように値が変化します。
このような値を変数にすることで、環境ごとに書き換えることなくアプリを運用することができるのです。
環境変数を使う目的
今回の環境変数を利用する目的は「共通する値を一元管理して、Dockerの運用を楽にする」です。
なので、必ずしも環境ごとに変化する値とは限りません。
Dockerで環境変数を利用する場所
3つあります。
- docker-compose.yml内で利用する
- Dockerfile内で利用する
- コンテナ内(アプリ内)で利用する
docker-compose.yml内で環境変数を利用する
いくつかの方法があります。
- docker-compose.ymlの中で環境変数を宣言する
docker-compose run
コマンド実行時にターミナル上から環境変数を渡す- .envファイルで環境変数を宣言する
今回は3の.envファイルを採用
今回は一元管理に最も適した3の「.envファイルで環境変数を宣言する」方法を採用します。
環境変数の流れ方は、
- .env => docker-compose.yml => /api/Dockerfile , /front/Dockerfile
- .env => docker-compose.yml => コンテナ
となります。
ENV命令からコンテナに渡すことも可能
ちなみに、「Dockerfile」内でENV
で宣言した値もコンテナ内に渡すことができます。
- .env => docker-compose.yml => /api/Dockerfile
ENV
, /front/DockerfileENV
=>コンテナ
ただこの方法、コードが無駄に増殖するので今回は採用しませんでした。
docker-compose.ymlで環境変数を展開する
docker-compose.ymlと同一パスにある「.env」という名前のファイルで宣言された環境変数は、自動で参照できるようになっています。
docker-compose.yml内では$
をつけて変数を展開します。
.env
WORKDIR=app
docker-compose.yml
# 環境変数を展開する
$WORKDIR
docker-compose.yml => Dockerfileへ環境変数を渡す方法
- 渡す側(docker-compose.yml)と
- 受け取る側(Dockerfile)双方の設定が必要です。
docker-compose.ymlから渡す
build
のargs
を使用します。
<キー: 値>形式で指定します。
docker-compose.yml
services:
api:
build:
context: ./api
args:
# キー: 値
WORKDIR: $WORKDIR
# この書き方でもOK
- WORKDIR=$WORKDIR
-
args
... Dockerイメージをビルド(作成)する際に引数を渡すために使用します。この仕組みを使ってDockerfileへ環境変数を渡します。
Dockerfileで受け取る
ARG
命令を使います。
指定する値はdocker-compose.ymlで渡したキーの名前です。
受け取った後はDockerfile内で変数として扱うことができます。
Dockerfile
ARG WORKDIR
ENV HOME=/${WORKDIR}
docker-compose.yml => コンテナへ環境変数を渡す方法
docker-compose.ymlからコンテナへ環境変数を渡す方法は2つあります。
1. environment
environment
を使用する場合は、<キー: 値>形式で環境変数を指定します。
これは扱う環境変数が少ない場合に使用します。
services:
api:
...
environment:
POSTGRES_PASSWORD: $POSTGRES_PASSWORD
# この書き方でもOK
- POSTGRES_PASSWORD=$POSTGRES_PASSWORD
2. env_file
env_file
を使用する場合は、環境変数を格納したファイルパスを指定します。
相対パス、絶対パスどちらでも構いません。
これは扱う環境変数が多い場合に使用します。
services:
api:
...
env_file: ./.env
env_fileで複数ファイルを指定する場合
複数のファイルを指定する場合は以下のように書きます。
env_file
で指定するファイル名は、.envに限らずなんでもOKです。
services:
api:
...
env_file:
- ./.env
- ./api/envfile
- ./front/envfile
コンテナに渡した環境変数をアプリで参照する
コンテナ内の環境変数はアプリケーション側で参照することができます。
ENV
を使って参照します。
ENV["POSTGRES_PASSWORD"]
Nuxt.jsで参照する
process.env
で参照します。
prosess.env.POSTGRES_PASSWORD
Nuxt.jsで本番環境の環境変数を参照するには?
今からするお話しは、Herokuへデプロイするプロジェクトファイルに「docker-compose.yml」が含まれていない場合のお話です。
前提として
- 開発環境では「docker-compose.yml」を使って環境変数を参照し、
- 本番環境では「Herokuサーバ」の環境変数を参照します。
あの、$ heroku config:set
で設定する変数のことですね。
ユニバーサルモードの場合はこれで問題ないと思います。サーバを参照できるので。
これについては確認を取っていない。
しかし、SPAモードではどうでしょう。
クライアントサイド(ブラウザ側)で稼働するモードなのでサーバを参照することができません。
そこで本番環境にも環境変数を渡すために「heroku.yml」を使ったデプロイを行います。
heroku.ymlとは何か?
heroku.ymlとは、本番環境のHerokuデプロイ時に参照される設定ファイルです。
どこのDockerfileを参照すればいいか、アプリの起動コマンドは何を実行するかなどの設定を記述します。
いわば本番用docker-compose.ymlファイルです。
heroku.ymlで環境変数を渡すには?
Dockerイメージをビルドするときにconfig
というキーで渡すことができます。
heroku.ymlのサンプル
build:
...
# ここでDockerfileに環境変数を渡す
config:
WORKDIR: app
API_URL: https://xxx.com
ただこの「heroku.yml」は、Dockerfileにしか環境変数を渡せません。
コンテナに直接渡すような命令はないのです。
Herokuからしたら当たり前ですね。コンテナに渡したかったら$ heroku config:set
でサーバに環境変数をセットしろと。
つまり?(まとめ)
つまり、筆者が伝えたかったことは
- Nuxt.jsのSPAモードを使用する場合、
- できるだけ本番環境に合わるために、
- 開発時の環境変数は、
args
を使ってDockerfileに渡そう
ということです。
もちろんdocker-compose内でenvironment
プロパティから環境変数を渡しても、SPAモードで参照することができます。ただこれは開発環境だけ。
デプロイ時にまた書き足す必要が出てくるのです。
まとめ
さて、長々となりましたが今回はDockerでの環境変数の扱い方ついて説明しました。
学んだことをまとめておきましょう。
- docker-compose.ymlで環境編集を参照する方法は3つある
- docker-compose.ymlで宣言する
- コマンド実行時にターミナルから宣言する
- 同じファイルパスの.envファイル内で宣言する
- docker-compose.yml => Dockerfileへ環境変数を渡す
- docker-compose.yml ...
build
のargs
を使って渡す - Dockerfile ...
ARG
命令で受け取る
- docker-compose.yml ...
- docker-compose.yml => コンテナへ渡す
- 扱う環境変数が少ない ...
environment
を使う - 扱う環境変数が多い ...
env_file
を使う
- 扱う環境変数が少ない ...
- コンテナに渡した環境変数をアプリで参照する方法
- Rails ...
ENV["POSTGRES_PASSWORD"]
- Nuxt.js ...
process.env
- Rails ...
- Nuxt.js SPAモードで環境変数を取り扱う場合
- 本番環境に合わせるために、
args
を使ってDockerfileに渡し運用する
- 本番環境に合わせるために、
次回予告
次回はdocker-compose.ymlファイルを編集していきます。
ここでお話ししたことも次回で繋がってきますので、ちんぷんかんぷんでも大丈夫!
どうぞ↓のリンクから。