Play Framework / Scala 再入門 3日目
3日目は
- Docker を導入する
- MySQL を Docker Container で動かす
- Playframework を Docker Container で動かす
をやりました。
今作っているアプリのディレクトリ構成
ざっとこんな感じ。
. ├── api ├── docker └── web
api/
ディレクトリは Playframework のプロジェクトが格納されている。web/
ディレクトリは現在空っぽで、フロントエンドのプロジェクトが格納される予定(Elm で作る予定)。docker/
ディレクトリは、これらのプロジェクトを Docker Container で動かす設定を格納する。
今日は、 docker/
の中身を実装していく。
MySQL をコンテナ上で動かす
これは何度もやっているのでサラッと。
ディレクトリ構造
. └── docker └── mysql ├── Dockerfile ├── conf.d │ └── custom.cnf ├── my.cnf └── sql └── create_database.sql
先程の docker/
ディレクトリに、この様な感じでファイルやディレクトリを追加。
Dockerfile
単純にこんな感じ
FROM mysql:5.7
conf.d / my.cnf
これらの MySQL の設定ファイルなどは、後ほど docker-compose.yaml
にてコンテナにマウントさせる。
sql/create_database.sql
今回は create database
が記載された単純な SQL ファイル。
コンテナ内の /docker-entrypoint-initdb.d
にマウントさせると初回自動でテーブルなどを作成してくれる。
こちらも後ほど docker-compose.yaml
にてコンテナにマウントさせる。
ただし、Database は後述の MYSQL_DATABASE
で作ってくれたりするし、今回は特に内容を記述していない。
Playframework をコンテナ上で動かす
ディレクトリ構造
API 用のディレクトリに Dockerfile を配置するだけ。
. └── api └── Dockerfile
Dockerfile
Dockerfile の中身はこんな感じ。
FROM hseeberger/scala-sbt:8u212_1.2.8_2.12.9 RUN mkdir /project-name WORKDIR /project-name ADD . /project-name RUN cd /project-name
イメージはコチラを利用。
https://hub.docker.com/r/hseeberger/scala-sbt/
Scala の version が今 2.12.8
なので、 scala-sbt:8u212_1.2.8_2.12.9
を選択。
2.13.x
にしないとなあ...。
ADD . /project-name
でプロジェクト内のソース(つまり Playframework のソース)を追加している。
WORKDIR /project-name
を設定しないと、立ち上げたときに下記のようなエラーが出るので注意。
| [error] java.lang.RuntimeException: No main class detected. | [error] at scala.sys.package$.error(package.scala:26) | [error] (Compile / bgRun) No main class detected. | [error] Total time: 1 s, completed Aug 16, 2019 9:39:16 AM
docker-compose.yaml の定義
こんな感じ。
version: '2' services: project_name_db: container_name: project_name_db image: project_name_db build: ./mysql ports: - "3306:3306" environment: MYSQL_DATABASE: project_name MYSQL_USER: root MYSQL_ALLOW_EMPTY_PASSWORD: "yes" volumes: - project_name_db_volume:/var/lib/mysql - "./mysql/sql:/docker-entrypoint-initdb.d" - "./mysql/conf.d/:/etc/mysql/conf.d/" - "./mysql/my.cnf:/etc/mysql/my.cnf" project_name_api: container_name: project_name_api image: project_name_api build: ../api command: sbt run volumes: - ../api:/project_name - project_name_api_volume:/project ports: - "9000:9000" depends_on: - project_name_db stdin_open: true tty: true volumes: project_name_db_volume: driver: local project_name_api_volume: driver: local
MySQL のコンテナ設定
下記が MySQL 用
project_name_db: container_name: project_name_db image: project_name_db build: ./mysql ports: - "3306:3306" environment: MYSQL_DATABASE: project_name MYSQL_USER: root MYSQL_ALLOW_EMPTY_PASSWORD: "yes" volumes: - project_name_db_volume:/var/lib/mysql - "./mysql/sql:/docker-entrypoint-initdb.d" - "./mysql/conf.d/:/etc/mysql/conf.d/" - "./mysql/my.cnf:/etc/mysql/my.cnf" volumes: project_name_db_volume: driver: local
コンテナ名を指定
container_name: project_name_db
イメージ名を指定
image: project_name_db
MySQL 用の Dockerfile の場所を指定
build: ./mysql
ポートを指定
ports: - "3306:3306"
環境変数を指定
MYSQL_DATABASE
を指定するとコンテナ起動時に Database を作成してくれる。
environment: MYSQL_DATABASE: project_name MYSQL_USER: root MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
volume を指定
volumes: - project_name_db_volume:/var/lib/mysql - "./mysql/sql:/docker-entrypoint-initdb.d" - "./mysql/conf.d/:/etc/mysql/conf.d/" - "./mysql/my.cnf:/etc/mysql/my.cnf"
volume について、下記が先程書いた初期SQL
- "./mysql/sql:/docker-entrypoint-initdb.d"
下記が MySQL の設定関連
- "./mysql/conf.d/:/etc/mysql/conf.d/" - "./mysql/my.cnf:/etc/mysql/my.cnf"
下記は、作成したデータベースなどをコンテナを消しても永続化させる設定
- project_name_db_volume:/var/lib/mysql
volume は下記コマンドで確認することが出来る
$ docker volume ls DRIVER VOLUME NAME local docker_project_name_db_volume
Playframework のコンテナ設定
下記が Playframework 用
project_name_api: container_name: project_name_api image: project_name_api build: ../api command: sbt run volumes: - ../api:/project_name - project_name_api_volume:/project ports: - "9000:9000" depends_on: - project_name_db stdin_open: true tty: true volumes: project_name_api_volume: driver: local
下記は MySQL と同じなので割愛
project_name_api: container_name: project_name_api image: project_name_api build: ../api ・・・ ports: - "9000:9000" ・・・
下記はコンテナを立ち上げたときに実行するコマンド。単純に sbt run
しているだけ。
command: sbt run
下記は、MySQL が立ち上がったら、当該 Playframework のコンテナを立ち上げるといったようなコンテナ間の依存関係の設定。
depends_on: - project_name_db
下記はコンテナ立ち上げっぱなし、コンソール表示、みたいな設定(チョー乱暴な説明)。まあ今更説明せんでも・・・なノリでご愛嬌。
stdin_open: true tty: true
同じく volume の設定。
volumes: - ../api:/project_name - project_name_api_project_volume:/project - project_name_api_target_volume:/target volumes: project_name_api_project_volume: driver: local project_name_api_target_volume: driver: local
volume に設定しておかないと、コンテナを立ち上げるたびに sbt の build が走ってしまうので、必ず設定する。
追記
どうにも docker-compose.yaml
を更新しただけで、sbt の build が走ってしまう。
volume をちゃんと読み込んでいる場合
[info] Loading settings for project project_name-build from plugins.sbt ... [info] Loading project definition from /project_name/project [info] Loading settings for project root from build.sbt ... [info] Set current project to api (in build file:/project_name/) --- (Running the application, auto-reloading is enabled) --- [info] p.c.s.AkkaHttpServer - Listening for HTTP on /0.0.0.0:9000 (Server started, use Enter to stop and go back to the console...)
docker-compose.yaml を編集すると再ビルドが・・・。
[info] Loading settings for project project_name-build from plugins.sbt ... [info] Loading project definition from /project_name/project [info] Updating ProjectRef(uri("file:/project_name/project/"), "project_name-build")...
ここらへんどうにかしないと Docker を入れると逆につらくなるので駄目だ。
やりたいこととしては、docker-compose build
したときだけ sbt の build を実行して欲しい。
うーむ。
ビルドや起動など
ここからは基本的に docker-compose
の作業。
下記ディレクトリに移動し
. └── docker
下記コマンドでビルドと実行する。
$ docker-compose up
Shell を作ってしまう
僕はこんなシェルを作ってしまっている。
- rwxr-xr-x build.sh
- rwxr-xr-x exec.sh
- rwxr-xr-x login.sh
- rwxr-xr-x restart.sh
- rwxr-xr-x start.sh
- rwxr-xr-x stop.sh
build.sh
単純にビルドしたい場合に利用
#!/bin/zsh docker-compose build $1 $2 $3 $4 $5 $6 $7 $8 $9
exec.sh
コンテナ内部に対して何らかのコマンドを実行したい場合に利用。
#!/bin/zsh docker-compose exec project_name_api $1 $2 $3 $4 $5 $6 $7 $8 $9
login.sh
コンテナ内部にログイン(表現間違っているかも)するときに利用。
#!/bin/zsh docker exec -it project_name_api /bin/bash
restart.sh
コンテナを再起動する。
#!/bin/zsh rm ../tmp/pids/server.pid docker-compose stop docker-compose up
start.sh
コンテナを起動する。
restart.sh
を使っているのでコチラはあまり使わない。
#!/bin/zsh rm ../tmp/pids/server.pid docker-compose up
stop.sh
コンテナを停止する。
#!/bin/zsh rm ../tmp/pids/server.pid docker-compose stop
下記を指定しているのは、時々プロセスが残ってしまうことがあったので。
rm ../tmp/pids/server.pid
前回
次回
MySQL と ScalikeJDBC の設定をしたいと思います。