Docker ComposeでPhoenix1.4（Eliixir1.8）+ MySQL5.7環境構築

## 概要

Phoenix+MySQLを触ってみたかったのでDockerで環境構築することにした。
初めてのElixir環境の構築なので指摘とかあれば嬉しいです。

この記事で書いた内容はgithubにあげてありますので参考にどうぞ。
https://github.com/hrs-o/docker-phoenix-mysql/

## 環境

### ローカルPC

```bash
$ docker --version
Docker version 18.09.1, build 4c52b90
$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01
```

### docker上のelixirバージョン

```bash
# elixir --version
Erlang/OTP 21 [erts-10.2.3] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [hipe]

Elixir 1.8.0 (compiled with Erlang/OTP 21)
```

## 手順

### ディレクトリなどなど作成

```bash
$ mkdir docker-exlixir
$ cd docker-elixir
$ mkdir -p docker/app
$ mkdir -p docker/mysql/data
$ touch docker/mysql/data/.gitkeep
```

### アプリサーバーのDockerファイルを作成

```bash
$ vim docker/app/Dockerfile
```

```dockerfile:docker/app/Dockerfile
FROM elixir:latest

ENV NODE_VERSION 11
ENV PHOENIX_VERSION 1.4.0

RUN apt-get update \
    && curl -sL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash \
    && apt-get install -y nodejs inotify-tools \
    && npm install n yarn -g \
    && n stable \
    && npm update -g npm \
    && mix local.hex --force \
    && mix archive.install --force hex phx_new ${PHOENIX_VERSION} \
    && mix local.rebar --force
```

### docker-compose.ymlの作成

mysqlのデータは永続化する想定になってます。

```bash
$ vim docker-compose.yml
```

```yml:docker-compose.yml
version: '3'

services:
  app:
    build: docker/app
    ports:
      - "4000:4000"
    environment:
      - MIX_ENV=dev
      - PORT=4000
    container_name: "myapp-app"
    command: mix phx.server
    working_dir: "/src"
    volumes:
      - ./:/src:cached
      # exclude volumes
      - /src/.git
      - /src/.idea
      - /src/docker
    links:
      - mysql

  mysql:
    image: mysql:5.7
    container_name: "myapp-mysql"
    restart: always
    environment:
      MYSQL_DATABASE: root
      DB_USERNAME: root
      MYSQL_ROOT_PASSWORD: root
    ports:
      - 13306:3306
    volumes:
      - ./docker/mysql/data:/var/lib/mysql
```

### Phoenixプロジェクトの生成

phx.newを行う際にdatabaseオプションを指定してmysql用に色々やってもらう。
それ以外はデフォルトのままyでインストールしていきます。

```bash
$ docker-compose build
$ docker-compose run app mix phx.new . --app myapp --database mysql
The directory /src already exists. Are you sure you want to continue? [Yn] y
Fetch and install dependencies? [Yn] y
```


### DB設定の変更

```bash
$ vim config/dev.exs
```

```diff:config/dev.exs
config :myapp, Myapp.Repo,
  username: "root",
- password: "",
+ password: "root",
- database: "myapp_dev",
+ database: "root",
- hostname: "localhost",
+ hostname: "myapp-mysql",
  pool_size: 10
```

### 一旦docker-composeを使ってサービスを開始する

```bash
$ docker-compose up --build -d
```

### サンプル用にuserに対してのCRUDを作成

[phx.gen.html](https://hexdocs.pm/phoenix/Mix.Tasks.Phx.Gen.Html.html)を使ってコントローラーやViewをさくっと作成

```bash
$ docker-compose exec app mix phx.gen.html Accounts User users name:string age:integer
$ docker-compose exec app mix ecto.migrate
$ vim lib/myapp_web/router.ex
```

```diff:lib/myapp_web/router.ex
  scope "/", MyappWeb do
    pipe_through :browser

    get "/", PageController, :index

+   resources "/users", UserController
  end
```

### アクセスして確認

正常に表示・動作されてれば環境構築完了、お疲れ様でした。

- デフォ画面
http://localhost:4000/

- userのCRUD確認
http://localhost:4000/users

## まとめ

参考にさせていただいた方の投稿のほぼママなので簡単に構築できました、ありがとうございます。
差分的にはphx.newする際のdatabaseの指定だけかなと思います。

ただ、この環境リモートデバッグとかブレークポイント貼ってデバッグとか出来ない（と思う）のでなかなか開発は難しそうだなというのが構築終わったあとの話。（JetBrains系IDE使いです。）


## 参考

https://phoenixframework.org/
https://qiita.com/Tsuyoshi84/items/336f31f6dcc2cd8a077b