そろそろ、自分のdocker-compose.yml周りを公開
docker便利ですね。
最近そんなことばかりしか言ってない気がします。
自分がdockerを使い始めた頃は、dockerってなんなのかわからない人が多く
話すと便利そうだけどプロダクションで使う想像がつかないとか
環境がめんど臭いとか
色々言われていました。
今現在は、開発環境として使うのであれば
docker for macというのがあって、これ入れるだけでかなり簡単にdockerが試せるようになりました。
環境を作るのが簡単になったのであれば、使えるdockerfileとかdocker-compose.ymlとかも
そろそろテンプレ的な何かがあった方が良いかな、と思い
今自分の手元でよく使っている構成でdocker-compose.ymlを公開してみます。
まずは、作りたい環境ですが
サーバサイドとしてRuby on Railsを使うことが多いので、Ruby on Railsを立ち上げる
という前提で行きます。
必要なコンテナとしては
- Ruby on Railsが動くコンテナ
このコンテナの中には
/productsというディレクトリを作って、この中にRuby on Railsのプロジェクトを置くようにします。
- mysqlが動くコンテナ
この二つが最低限なので、この構成を作って行きます。
まずは手元にRuby on Railsのプロジェクトを適当に作ります。
rails new docker-compose-template
docker-compose-templateの中に入ってDockerfileを作成します。
主な構成ですが、プロジェクトのファイル以外に以下のようなファイルが追加になります。
docker-compose-template ┣Dockerfiles ┃┗mysql ┃ ┣conf.d ┃ ┃┗default.cnf ┃ ┗docker-entrypoint-initdb.d ┃ ┗init-user-db.sh ┣Dockerfile ┣docker-compose.yml ┗entrypoint.yml
それぞれのファイルについて中身とその解説をして行きます。
#Dockerfile
# 本体 # # VERSION 0.0.1 FROM gendosu/ruby-for-rails:2.3 MAINTAINER Gen Takahashi "gendosu@gmail.com" ADD . /products WORKDIR /products RUN chmod a+x /products/entrypoint.sh RUN ./entrypoint.sh ENTRYPOINT ["./entrypoint.sh"]
FROMのベースになるイメージは、officialのrubyにRuby on Railsで良く使うパッケージを追加したものを使用しています。
あと、特徴は
entrypoint.shという物を作成しており、ここで毎回コンテナ起動するたびに実行したい処理などを入れておきます。
#entrypoint.sh
#!/bin/bash set -e bundle rake db:migrate # rake db:seed if [ -e /products/tmp/pids/*.pid ]; then rm /products/tmp/pids/*.pid; fi exec "$@"
bundle、db:migrate、pidファイル削除などを毎回起動時に行う
#Dockerfiles/mysql/conf.d/default.cnf
[client] socket=/var/run/mysqld/mysqld.sock [mysql] max_allowed_packet=16M socket=/var/run/mysqld/mysqld.sock [mysqld] character-set-server = utf8 max_allowed_packet=16M socket=/var/run/mysqld/mysqld.sock [mysqld_safe] character-set-server = utf8 max_allowed_packet=16M socket=/var/run/mysqld/mysqld.sock
mysqlのコンテナで、新らし目のコンテナだとsocketの置き場所が変わったりしているので
後ほどdocker-compose.ymlでmysqlのバージョン指定はしますが、今回はdockerのofficialのmysql:5.5.54を前提に書きます。
#Dockerfiles/mysql/docker-entrypoint-initdb.d/init-user-db.sh
#!/bin/bash set -e mysql -uroot -p"$MYSQL_ROOT_PASSWORD" <<-EOSQL CREATE DATABASE example_development; CREATE DATABASE example_test; EOSQL mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -Dexample_development < /docker-entrypoint-initdb.d/example.dmp
mysqlインスタンスの初回起動時に実行されるスクリプトになります。
これはofficialのmysqlで、コンテナ内の
/docker-entrypoint-initdb.d
というディレクトリに置かれたシェルはインスタンスの作成時に実行される
という仕組みがあるので、そこにファイルを置くように設定します。
(あとでdocker-compose.ymlでファイルを指定します)
最後、docker-compose.yml
#docker-compose.yml
version: "2" services: # # メインコンテナ # main: build: . depends_on: - "mysql" volumes: - .:/products ports: - "3000:3000" environment: RAILS_ENV: development DATABASE_URL: mysql2://root:root@mysql/example_development command: rails s -b 0.0.0.0 -p 3000 # # MySQLのコンテナ # mysql: image: mysql:5.5.54 environment: - MYSQL_ROOT_PASSWORD=root volumes: - "./Dockerfiles/mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d" - "./Dockerfiles/mysql/conf.d:/etc/mysql/conf.d" ports: - "3306:3306"
ここまでで、docker-compose.ymlでRuby on Railsを起動するために必要なものは完成しました。
プロジェクトを起動するには
docker-compose up main
とやると、mysqlを起動して
init-user-db.shによってデータベースが作成され
その後にmainコンテナが起動して
entrypoint.shで初期化されて
プロジェクトが起動します。
init-user-db.sh
は、色々とカスタマイズすることで、すでにマイグレーションされたmysqlのダンプを置いて
それを初期データとして投入したり出来ます。
そうすると、
docker-compose stop docker-compose rm mysql docker-compose up main
とするだけで、データベースの初期化が完了します。
また、entrypoint.shで細工しているので
docker-compose up main
の時はdocker-compose.ymlに指定したcommandが実行されてプロジェクトが起動します。
railsコマンドを叩きたい時は
docker-compose run --rm main rake routes
とやると、コマンドが実行出来るようになっています。
なるべくシンプル構成でなるべく便利に使う想定で、今回このテンプレートっぽいファイルを作ってみました。
参考にしていただけたら幸いです。
一応githubリポジトリ
https://github.com/gendosu/docker-compose-template