備忘録

働きたくないでござる

Elixir, Phoenix の開発環境を Docker で構築

あまりにもわからないこと多すぎて、しばらくコードを書くのを諦めて読書してました。

とりあえず Elixir 触るなら プログラミング Elixir は必読かなという感覚です。

プログラミングElixir

プログラミングElixir

というわけで本格的に開発に入っていきたいのですが、その前に開発環境を Docker で作成したいと思います。

事前準備

macOS 上に環境構築するので Docker for mac をインストールします。
あと、ローカル環境で mix 動かしたりするので Elixir, mix, hex, phoenix あたりもインストールします。 ちなみに RDBMySQL を想定しています。

プロジェクト作成

プロジェクト作成はローカル環境で行います。
Docker 上でプロジェクト作成から Docker 上でやるのはちょっと面倒だなと思ったのだけど、スマートな方法ってあるのだろうか……?

$ mix local.hex
$ mix archive.install https://github.com/phoenixframework/archives/raw/master/phx_new.ez
$ mix phx.new docker_sample --database mysql
...
* creating docker_sample/assets/static/robots.txt
* creating docker_sample/assets/static/images/phoenix.png
* creating docker_sample/assets/static/favicon.ico

Fetch and install dependencies? [Yn] Y

ファイルたちを準備

以下をコピペしつつ環境に合わせて微調整してください。

Dockerfile

FROM elixir:latest

ARG app_path
ARG app_port
ENV APP_PORT $app_port

WORKDIR $app_path
EXPOSE $app_port

RUN \
  set -x && \
  apt-get update && \
  apt-get install -y \
    nodejs \
    npm \
    mysql-client \
    inotify-tools \
    git \
    --no-install-recommends && \
  rm -rf /var/lib/apt/lists/* && \
  npm cache clean && \
  npm install n -g && \
  n stable && \
  ln -sf /usr/local/bin/node /usr/bin/node && \
  apt-get purge -y nodejs npm

COPY . $app_path

RUN mix local.hex --force
RUN mix local.rebar --force

CMD ["mix", "phx.server"]

docker-compose.yml

version: '3.1'
services:
  mysql:
    image: mysql:5.7.10
    environment:
      MYSQL_ROOT_PASSWORD: secret
    volumes:
      - ./datadir/mysql/:/var/lib/mysql
  app:
    build:
      context: .
      args:
        app_path: /var/src/app
        app_port: 4000
    ports:
      - '4000:4000'
    volumes:
      - .:/var/src/app
    links:
      - mysql

.dockerignore

Dockerfile を編集する度に COPY で毎回キャッシュが使われなくてうるさいので……。

Dockerfile
docker-compose.yml
.git
.gitignore

config/dev.exs

config :docker_sample, DockerSample.Repo,
  adapter: Ecto.Adapters.MySQL,
  username: "root",
- password: "",
+ password: "secret",
  database: "docker_sample_dev",
- hostname: "localhost",
+ hostname: "mysql",

build, up

$ docker-compose build
$ docker-compose run app mix deps.get
$ docker-compose up -d
$ docker-compose exec app mix ecto.create

これで完了のはず?

課題

  • ローカルで docker-compose run app mix deps.get するのいけてない印象がある。
    (docker-compose build するだけで mix.lock が更新されてしまう可能性があるのも気持ち悪い気がするので、悩ましい)
  • umbrella プロジェクトを使ってみたいと思っているので、その時にまた作り直す必要がある。
  • MySQLレプリケーションをしたいのだけど、 複数の Dockerfile をどういうディレクトリ構造で配置するのがベストなのかわからない。

参考

Dockerfile の作り方勉強させていただきました。 感謝 m( )m

qiita.com

h3poteto.hatenablog.com