この記事は、「Elixir Advent Calendar 2020」8日目の記事です。
きのうは@koyo-miyamuraさんの「Elixirで動的計画法(DP)を実装してみた(Goとの比較つき)」でした!
概要
Elixir製のフレームワーク**Phoenix**によるWebアプリケーション開発を__Docker__でやる。
- シリーズ第1回の本記事では、
__Phoenix__コンテナと__DB(PostgreSQL)__コンテナとの連携確認をかねて、CRUD Web UI実装からテストまで行います。 - 次回シリーズ第2回目で、CIパイプラインを導入します。
実行環境
バージョン | 備考 | |
---|---|---|
macOS | ||
Docker (docker-compose) | ||
Elixir | 1.11.2 | compiled with Erlang/OTP 23 |
Phoenix | 1.5.7 | |
PostgreSQL | 12.4 | |
Node.js | 14.15.1 |
ディレクトリ構成(Phoenixプロジェクト作成前)
.
├── .env
├── app
│ └── Dockerfile
├── db
│ └── Dockerfile
└── docker-compose.yml
コード
PROJECT_NAME=my_app
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
POSTGRES_DB=testdb
POSTGRES_PORT=5432
FROM elixir:1.11.2-slim
WORKDIR /usr/src/app
RUN apt-get update -y && \
apt-get upgrade -y && \
apt-get install -y \
build-essential \
curl \
git \
gzip \
inotify-tools \
ssh \
sudo \
tar
RUN apt-get install -y nodejs npm
RUN npm install -g n
RUN n 14.15.1
RUN apt-get purge -y nodejs npm
RUN yes | mix local.hex
RUN mix local.rebar --force
RUN mix archive.install hex phx_new 1.5.7 --force
RUN apt-get clean
CMD [ "mix", "phx.server" ]
FROM postgres:12.4-alpine
ENV LANG ja_JP.utf8
version: "3"
networks:
backend:
driver: bridge
services:
app:
build: ./app
volumes:
- ./app:/usr/src/app
ports:
- 4000:4000
stdin_open: true
tty: true
command:
sh -c "cd ${PROJECT_NAME} && mix phx.server"
networks:
- backend
db:
build: ./db
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
ports:
- ${POSTGRES_PORT}:5432
volumes:
- ./db/postgres/tmp/data:/var/lib/postgresql/data
restart: always
networks:
- backend
コンテナ開発環境構築
上記コードを、ご自分の開発環境に準備しましょう。
用意がととのったら、以下の手順で環境構築をしていきます。
ビルド 〜 Phoenixプロジェクトディレクトリ作成
ビルドします。
$ docker-compose build
ビルドが済んだら、
- appコンテナ
- dbコンテナ
がきちんと用意できているか確認します。
$ docker-compose run --rm app elixir --version
Elixir 1.11.2 (compiled with Erlang/OTP 23)
$ docker-compose run --rm app mix archive
* hex-0.20.6
* phx_new-1.5.7
$ docker-compose run --rm db psql --version
psql (PostgreSQL) 12.4
$ docker-compose run --rm app bash -c "node --version && npm --version"
v14.15.1
6.14.8
大丈夫そうです。
つづいて、Phoenixプロジェクトをmy_app
という名前で作成していきます。
$ docker-compose run --rm app mix phx.new my_app
.
.
(途中で表示される`Fetch and install dependencies? [Yn]`には、`Y`で進めます)
.
.
We are almost there! The following steps are missing:
$ cd my_app
Then configure your database in config/dev.exs and run:
$ mix ecto.create
Start your Phoenix app with:
$ mix phx.server
You can also run your app inside IEx (Interactive Elixir) as:
$ iex -S mix phx.server
生成されたファイルの中身を書き換えます。
# Configure your database
config :my_app, MyApp.Repo,
username: "postgres", # <-- update
password: "password", # <-- update
database: "testdb", # <-- update
hostname: "db", # <-- update
-
.env
で設定してある環境変数をつかっています。
コンテナ起動します。
$ docker-compose up -d
きちんと起動しているか、確認します。
$ docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------------
................._app_1 sh -c cd my_app/ && mix ph ... Up 0.0.0.0:4000->4000/tcp
................._db_1 docker-entrypoint.sh postgres Up 0.0.0.0:5432->5432/tcp
よさそうです。
ここで mix ecto.create
やっておきます。
$ docker-compose run --rm app bash -c "cd my_app && mix ecto.create"
コンテナを再起動します。
$ docker-compose restart app
ここまでできたら、Webブラウザで「http://localhost:4000」を確認しましょう。
以下のようなWelcome画面が表示されたらOKです!
-
docker-compose logs
をたたいて、ログ中にエラーが出ていないか念のため確認しておきましょう。
CRUD WebUI実装
それでは、CRUD機能を実装していきます。
お題として、シンプルな__Usersリスト__を作っていきましょう。
まずは、取りあつかう情報をまとめてみます。
項目名 | |
---|---|
コンテキスト名 | Accounts |
スキーマ名 | User |
テーブル名 | users |
カラム : 型 | name:string email:string bio:string |
こちらの内容にもとづいて、生成コマンド mix phx.gen.html
を実行します。
$ docker-compose exec app bash -c "cd my_app && \
mix phx.gen.html Accounts User users name:string email:string bio:string"
ルーティングを設定します。
scope "/", MyAppWeb do
pipe_through(:browser)
get("/", PageController, :index)
resources "/users", UserController # --> add
end
マイグレーションを実行します。
$ docker-compose exec app bash -c "cd my_app && mix ecto.migrate"
その後、コンテナを再起動しておきましょう。
$ docker-compose restart app
ブラウザで「https://localhost:4000/users/new」を確認します。
CRUD WebUIが爆誕したことを確認できました!
テスト
テスト側の設定として、DB接続情報を更新します。
config :my_app, MyApp.Repo,
username: "postgres", # --> update
password: "password", # --> update
database: "my_app_test#{System.get_env("MIX_TEST_PARTITION")}",
hostname: "db", # --> update
pool: Ecto.Adapters.SQL.Sandbox
もしフォーマッターを入れてなかったら、このタイミングでmix format
を走らせておきましょう。
$ docker-compose exec app bash -c "cd my_app && mix format"
テスト実行します。
$ docker-compose exec app bash -c "cd my_app && mix test"
Compiling 23 files (.ex)
Generated my_app app
...................
Finished in 0.9 seconds
19 tests, 0 failures
All Greenでパスしていることを確認できました!
おわりに & 次回
今回、Phoenix + DBのDockerコンテナ開発環境を構築しました!
次回は、こちらのコンテナ開発環境にCIパイプラインを導入していきます。
明日の「Elixir Advent Calendar 2020」9日目は、@kobae964さんです。お楽しみに!
お知らせ
kokura.ex
北九州小倉のElixirコミュニティ__「kokura.ex」__は、福岡市で2017年から人気を博しているElixirコミュニティ「fukuoka.ex」が小倉にブランチした、新生__Elixirコミュニティ__です。
fukuoka.ex同様、
- 「高速処理性能」と「高い開発効率性」を両立できるプログラミング言語「Elixir」
- そのWebアプリケーションフレームワーク「Phoenix」
を、北九州を起点として広め、ワイワイ盛り上げていくコミュニティです。
これから先端技術をやりたい方や、最新のプログラミングを学びたい方、未来に向けてITに強くなりたい方など、技術への興味レベルが高い方や、プログラミングに関心が高い方のご参加を歓迎します。
__オンラインでのもくもく勉強会__を、__毎月ペースで開催__しておりますのでぜひどうぞ。
(はじめてElixirに触れる方も、お気軽にご参加ください!)
- イベントページ fukuoka.ex
connpassイベント一覧より、__kokura.ex__のページをご覧いただけます
fukuoka.ex アドベントカレンダー
「fukuoka.ex Elixir/Phoenix Advent Calendar 2020」もありますので、こちらもぜひどうぞ。
12/22の枠に自分も執筆参加してますので、よろしかったらご覧ください!