Phoenix API サーバーの Docker 化
Postgres を docker run -d --rm ...
して、 Phoenix サーバーを mix phx.server
して、というのにだんだん「ムキーッ」ってなってきたので Docker コンテナ化をすることにした。
ちなみに JavaScript などフロントエンドの部分は今回はなかったので面倒がより少なかった。
やること#
- 開発環境用のコンテナを作る
- いったんプロダクションコンテナのことは考えない
- 頑張って容量削ったりもしない
docker-compose up
とやると Phoenix サーバーと Postgres サーバーが立ち上がって mix ecto.setup; mix phx.server
されるという状態をゴールにする。
やったこと#
Dockerfile#
まず Dockerfile を書く。
FROM elixir:1.8.1
RUN mkdir -p /src
COPY ./ /src/
WORKDIR /src/
RUN mix local.hex --force \
&& mix local.rebar --force \
&& mix deps.get
ENV MIX_DEV=dev
EXPOSE 8000
CMD ["/src/setup.sh"]
全部 COPY
している都合いろいろと不要なものも混じるので .dockerignore
をいろいろ設定する。本当は COPY
するファイルやディレクトリを逐一指定したほうがいいのかもしれない。
shell#
セットアップするシェルスクリプト(Dockerfile の setup.sh
)を書く。といっても mix
を使うだけ。
#!/bin/sh
mix ecto.setup
PORT=8000 mix phx.server # デフォルトのポート番号は 4000
docker-compose の設定#
version: "3"
services:
postgres:
image: "postgres:11.2"
ports:
- "5432:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
core_api:
build: .
ports:
- "8000:8000"
environment:
POSTGRES_HOST: postgres
depends_on:
- postgres
links:
- postgres
もしかしたら links
があれば depends_on
は要らないかも。
config/dev.exs の設定#
Postgres のホスト名を links で指定した名前にする必要があるので、ここでちょこっとだけ Elixir のコードを書く。といってもほんとにちょこっとだけ。
データベースの設定の hostname: "localhost"
を次のように指定。
# config/dev.exs
# Configure your database
config :api, Api.Repo,
username: "postgres",
password: "postgres",
database: "api_dev",
hostname: "localhost",
hostname: System.get_env("POSTGRES_HOST") || "localhost",
pool_size: 10
環境変数 POSTGRES_HOST
があればその値を、なければ "localhost"
を採用するパターンマッチを書いただけ。
おわり#
この状態で docker-compose up
をやると無事に起動します。めでたしめでたし。