14
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Elixir/Phoenix+MySQL5.7環境をDocker/Docker Composeで整え開発する。

Last updated at Posted at 2019-01-08

Elixir/Phoenix+MySQL5.7環境をDocker/Docker Composeで整え開発する。

##この記事を書いた理由1
手元の開発コンピュータが何であっても良いように開発環境を、いまさら・・Dockerの勉強も踏まえてみましたので、その共有です。

##この記事を書いた理由2
あー、これでApache、NginX、MySQLは、XAMPPやMAMPのやつ使って、足りないものはOS(MacOSX、Windows10などなど)にインストールして〜・・・ってのがなくなるし、新しいメンバーに開発環境整えてもらう時に、「動かないんですけど・・」で苦労することもなくなる〜。実際、社内でも、そうしてます。:grin:

##注意点
私がMacOSXを使用しているので、細かいターミナルでの操作などは、OSXベースになりますが、Windows10など、その他の方も、ほとんど同じなはずなので参考になると思います。

また今回はDockerを使用しています。DockerDesktopをインストールするなどしてください。Windows10では、Dockerは、確か、Professionalじゃないと動かなかったような気もしていますので、そのあたりは・・ご了承ください。 :bow_tone2:

またDockerについては、細かく説明は、していません。

##キーワード

  • Elixir
  • Phoenix
  • Docker
  • Docker Compose

##アジェンダ

  1. Elixirの環境をDockerで起動できるようになる。
  • Docker初体験
  1. 1.の環境(Dockerコンテナ)でPhoenixプロジェクトを作成して起動してみる。
  • Phoenixプロジェクト作成・初体験
  1. MySQLもDockerで起動してPhoenixプロジェクトでDBも使えるようになる。
    • DockerComposeで、複数Dockerをまとめる。
    • プロジェクト一式をローカルPCにコピーする。
  2. 日々の開発が出来るか?確認する。
    • 1日が終わってdocker-compose down。次の日に開発環境を起動する。

##1. Elixirの環境をDockerで起動できるようになる。
###1-1. 作業ディレクトリを作成する
ホームディレクトリ直下に、適当な作業ディレクトリを作成することにします。
とりあえず、ここでは、elixerというディレクトリを作成しました。

mkdir ~/elixir
cd elixir

###1-2. ElixirのDockerfileを作成する
テキストエディタで以下のようにDockerfileを作成します。

Dockerfile
FROM elixir:alpine

###1-3. DockerでElixir環境を起動してみる。
早速、Elixirの環境を起動?してみましょう。Docker初めてな人は、起動というと変な感じかもですが。
まず、Dockerfileで記述した内容のものをbuildします。elixir_sampleという名前にしています。

docker build -t elixir_sample .

buildできたら、起動します。

docker run -p 4000:4000 -i -t elixir_sample /bin/ash

実行後、iexというコマンドを実行して、ex(1)> というのが出ていたら成功っす。

##2. 1.の環境(Dockerコンテナ)でPhoenixプロジェクトを作成して起動してみる。
###2-1. Phoenixフレームワークのインストール
1-3.のiex状態な人は、ctl+cを2回押してコマンド待ち状態になってください。そして以下のコマンドを実行します。

mix archive.install hex phx_new 1.4.0

途中、[Yn]と聞かれますが、何も考えずYで。

###2-2. プロジェクトを作成してみる。
このコマンドでsample_dbというプロジェクトを作成します。Phoenixフレームワークは、postgresqlがデフォルトDBになっているんですが、今回はMySQLを使用したいので、--databaseオプションで指定しています。

あ、、この時点では、まだMySQLサーバ自体は、ローカルにインストールも起動もされていません。sample_dbプロジェクトで使用するデータベース・サーバの指定のみです。

2-1.と同様に途中で[Yn]と聞かれますがYで。

mix phx.new sample_db --no-webpack --database=mysql

###2-3. プロジェクト起動してみる。
ここまでで、プロジェクトを起動してみましょう。
下のコマンドを実行します。

cd sample_db
iex -S mix phx.server

そして、少々待つと、

[info] Running SampleDbWeb.Endpoint with cowboy 2.6.1 at http://localhost:4000

と表示されます。

さらに、まだデータベースが用意されていないため、接続エラーズラズラと表示されます。

[error] Mariaex.Protocol (#PID<0.2550.0>) failed to connect: ** (Mariaex.Error) tcp connect: econnrefused

が、、そんなものは、無視して:ok_hand:、ブラウザにlocalhost:4000と入力して、
sample_dbプロジェクトが無事起動しているかを確認しましょう。

スクリーンショット 2019-01-07 0.48.34.png こんな風に表示されました? :lollipop:

###2-4. データベースの設定
接続先のデータベースは未だ作ってないのですが、
その前に、Phoenixプロジェクト内のデータベースに関する設定をやっちゃいます。

cd config
vi dev.exs

として、設定ファイルdev.exsを開いて、
下のようにデータベースに関する部分を修正して保存します。

修正したのは、passwordの値とhostnameです。

passwordは、あとで作成するデータベースsample_db_devへの接続パスワードなので、
自由に設定してもらってOKです。ここでは root としています。

また、hostnameはデフォルトでlocalhostとなっているのですが、
db というものにしています。

localhostじゃないとダメなんじゃ・・? って思う方もいらっしゃるかもですが、
ここは、後述のDockerCompose関連が理由で、そうやっています。


config :sample_db, SampleDb.Repo,
  username: "root",
  password: "root",
  database: "sample_db_dev",
  hostname: "db",
  pool_size: 10

###2-5. プロジェクトファイル群をローカルPCにコピー
2-2.で作成したsample_dbプロジェクトは、あくまでDockerコンテナに存在するリソースになります。つまり、これらのファイルを参照するためにはDockerコンテナに入る必要があります。

ということは・・・毎回(毎日?)、dockerコンテナ内にコマンド打って入って、
さらに、そのコンテナ内からファイルをさわる・・必要がある??

コンテナ内のファイルって、コンテナ外にあるテキストエディタで修正したり出来るのかな・・?
*この方法をジックリ調べていないので、次の様にしています。:innocent:

私は、ローカルPCに、このプロジェクト一式をコピーし、Dockerコンテナ起動時にDockerコンテナにマウントする方法をとるようにしています。マウントについては、後述しますので、その準備として、ローカルPCにコピーします。

今、起動しているelixir_sampleコンテナを終了せずに、
新しいターミナルウィンドウを開いて、次のコマンドを打ちます。

docker ps

すると、次のように表示されるのでコンテナIDをコピーします。
ここでは、fe7dd49baeb5 です。


CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS
fe7dd49baeb5        elixir_sample       "/bin/ash"          About a minute ago   Up About a minute   0.0.0.0:4000->4000/tcp   

つづけてローカルPCにコピーしていきます。

docker cp fe7dd49baeb5:sample_db .

sample_dbディレクトリ一式がローカルの~/elixir/sample_dbとしてコピーされていますか?

##3. MySQLもDockerで起動してPhoenixプロジェクトでDBも使えるようになる。
###3-1. MySQL用のDockerfileを用意する
~/elixir/mysqlディレクトリを作成して以下のDockerfileを用意します。

mysql/Dockerfile
FROM mysql:5.7

###3-2. Elixir用のDockerfileファイルの修正
以下のように2行目以降を追加しておいてください。

Dockerifle
FROM elixir:alpine

RUN mkdir /app
WORKDIR /app

RUN yes | mix local.hex
RUN yes | mix archive.install https://github.com/phoenixframework/archives/raw/master/phx_new.ez
RUN mix local.rebar --force
RUN apk update && \
    apk upgrade && \
    apk add --update\
    bash \
    curl-dev \
    gcc \
    g++ \
    make \
    git \
    nodejs \
    nodejs-npm \
    && rm -rf /var/cache/apk/*

###3-3. docker-compose.ymlファイルの作成
3-1.で、MySQLサーバもDockerで起動することが出来るのですが、このままだとDocker runをElixirとMySQLを使えるようになるために2回打たないといけません。こんな感じだと、そのほかのミドルウェアが必要になるたびにDocker runコマンドを打つ回数も増えます。

しかも、起動した後に、それぞれのサービスに対して毎回、、

1. 決まったコマンドを実行する必要があったり、
2. ボリューム(ローカルPCのディレクトリ領域を各サービスのDocker領域から共有したい)のマウントが必要になったり、、

すると、毎回コマンドを打つだけで大変ですし、その管理も大変になってしまいます。

そんなのを、まとめて管理してくれるのがDocker Composeです。
Docker Composeの詳しいことは、ネット上に詳しい方々がいらっしゃいますので、そちらなどを参照してください。:sunglasses:

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

  db:
    build: mysql/
    volumes:
      - ./mysql_lib:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root
    ports:
      - "3306:3306"

  app:
    build: .
    tty: true
    volumes:
      - ./sample_db:/app
    ports:
      - "4000:4000"
    command: ash -c "mix deps.get && mix phx.server"
    depends_on:
      - db

volumes:
  mysql:
    driver: local

ここで行われていることを、ちょっとだけ説明しておきます。

  • db:

    • db: は、MySQLコンテナの参照名にもなります。そのため2-4.でプロジェクトからMySQLへの接続に関してhostnameをdbにしています。
    • volumes:でやっているのは、 MySQLのDockerコンテナにある/var/lib/mysqlフォルダをローカルPC上の~/elixir/mysql_libにマウントしています。これは、データベース(のデータ)をローカルPC上に持っておきたい(=永続化)ためです。そーじゃなかったら、やらなくてOKです。Dockerイメージを削除したりすると、データベース自体が消えてしまうので、毎回データベース作る必要が出てきます。それでも大丈夫だったら、やんなくてOKです。
    • portsは、指定しなくても起動できるんですが、私は、MySQLWorkbenchをMacOSXで使っていて、ポート指定をしていないと、DockerコンテナのMySQLに接続できなかった(正確には、出来そうなのですが、ややこしい?)ので、指定しています。
  • app:

    • volumes: では、2.5でローカルにコピーしていたプロジェクトをDockerコンテナ内にマウントしています。こーすることによって、プロジェクトファイルをローカルPC上から直接編集できるようになり、且つElixir/Phoenix環境が存在するDockerコンテナを利用して、このプロジェクトを実行することが出来ます。

###3-4. コンテナ(ElixirとMySQL)の同時起動
では、DockerComposeでElixir/Phoenix環境とMySQL環境を同時に起動します。
docker-composeコマンドを実行する前に、現在起動しているコンテナをstopしておきます。
そうしないと、既に4000ポートを、このコンテナ(elixir_sample)が使用しているので、起動できないっす。

ターミナルからdocker psコマンドを叩いて、コンテナIDを確認します。

docker ps

コンテナIDが確認できたら、次のコマンドを実行します。

docker stop コンテナID

ここまで出来たら、docker-composeコマンドで一気に2つのコンテナを作成してみましょう。

docker-compose up

2-3.の時と同様に、まだデータベースが作成されていないので、次の用に接続エラーが表示されると思いますが、一旦OKです。
ブラウザにlocalhost:4000で同じくPhoenixフレームワークの画面が表示されるかを確認してください。

###3-5. データベースの作成
とりあえず、このままでも、この記事の目的としては、大丈夫なのですが、データベース接続エラーが、気持ち悪いので、MySQLコンテナに入ってデータベースを作成してみましょう。docker psコマンドでMySQLコンテナのコンテナIDを確認しコピーします。

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
b07acadbaa95        elixir_db           "docker-entrypoint.s…"   14 minutes ago      Up 5 minutes        0.0.0.0:3306->3306/tcp, 33060/tcp   elixir_db_1

2つコンテナが確認できますが、データベースのコンテナは、このように**"_db"**という名前が付いていると思います。
では、続いてコンテナの中に入りましょう。

docker exec -it b07acadbaa95 /bin/bash

コンテナに入れたら、mysqlサーバーに接続して、データベースを作成します。データベース名は、2-4.のconfig/dev.exsに書かれてあったsample_db_devです。

mysql -uroot -proot
create database sample_db_dev default character set utf8;

作成できたら、一旦コンテナを停止して、再度起動します。

docker-compose down
docker-compose up

データベース接続エラーは、なくなりましたでしょうか?

##4. 日々の開発が出来るか?確認する。
###4-1. 1日の開始|コンテナ起動
これまでの おさらいになっちゃいますが、念のため書いておこうと思います。
作業を開始する時は、PCを起動して、以下のコマンドでコンテナを起動します。

cd ~/elixir
docker-compose up

###4-2. 作業
ソースコードは、~/elixir/sample_dbとしてプロジェクトファイルがありますので、それを修正していきます。
docker-compose.ymlで、Dockerコンテナ内にマウントしているので、ローカルPC上のソース・ファイルを直接、好きなエディタで編集可能です。

確認もブラウザなりから4000ポートを経由すれば出来ます。
あとは、gitにコミットしたりですね。

###4-3. 1日の終わり
dockerコンテナを停止して、PCの電源切りましょう。:tools:

docker-compose down

##まとめ
Elixir/Phoenixの開発環境のイメージと、Docker,DockerComposeを未だ使っていない方の、とっかかり や参考になれば嬉しいです。もっと、こんな方法があるよ! や、間違っている箇所があれば教えてください。:confounded: 次回は、、Distilleryのデプロイ手法か、datadogで、Elixir/Phoenixの吐くログを見る設定なんかを投稿しようかと思っています(予定は未定)。

14
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?