#対象
まったくのdocker初心者がクイックスタート・ガイド:Docker Compose と Railsを一通りやっても、いまいち納得できなかった人。つまり私。
#目的
ある程度モヤモヤをスッキリさせて開発環境の雛型みたいなものまで持っていきたい。
#私の行った手順
クイックスタート・ガイド:Docker Compose と Railsを一読したことを前提に書いていきます。
##dockerディレクトリの作成
クイックスタートを一通り実行するとアプリケーションルートにDockerfileやdocker-compose.ymlがあるのが気になります。docker-compose.ymlはここにあるのがベターに思えますが、今後Nginxを組み込んだり、MySqlの永続化を考えるとdocker関連は一か所に押し込めたくなります。
そんなわけで、以下のディレクトリ構成にしました。
全ファイルをGitHub上に置いておきます。
docker-rails/
|-docker-compose.yml #これはこの場にあったほうがいい
|-Gemfile
|-Gemfile.lock
|-docker/
|-mysql/
| |-password.yml #MySQLのパスワードはここに記述
| |-volumes/ #このフォルダにMySQLのデータを永続化
|-rails/
| |-Dockerfile #Rails用のDockerfile
##プロジェクトの定義
###Dockerfileの作成
apt-getをMySQL用に変更。Gemfileは/tmpに置く。
FROM ruby:2.3.3
ENV LANG C.UTF-8
# for MySQL
RUN apt-get update -qq && apt-get install -y build-essential mysql-client nodejs
RUN gem install bundler
WORKDIR /tmp
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
RUN bundle install
ENV APP_HOME /myapp
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME
ADD . $APP_HOME
###Gemfileを作成
変更点無し
証明書エラーで落ちる時はhttp://rubygems.org
から持ってくる。
source 'http://rubygems.org'
gem 'rails', '5.0.1'
###Gemfile.lock(空ファイル)を作成
変更点無し
$touch Gemfile.lock
###docker-compose.ymlを作成
変更箇所は以下の通り。
- dbの
volumes
でデータベースを永続化 - dbの
extends
でパスワードをpassword.ymlで管理 - webの
extends
でパスワードをrailsにも教える。 -
extends
先のファイルにパスワードを設定。 - webの
build
でDockerfileの場所を指定。
version: '2'
services:
db:
image: mysql:5.7.17
ports:
- "3306:3306"
volumes:
- ./docker/mysql/volumes:/var/lib/mysql
extends:
file: ./docker/mysql/password.yml
service: password
web:
build:
context: .
dockerfile: ./docker/rails/Dockerfile
command: bundle exec rails s -p 3000 -b '0.0.0.0'
ports:
- "3000:3000"
volumes:
- .:/myapp
environment:
RAILS_ENV: development
extends:
file: ./docker/mysql/password.yml
service: password
depends_on:
- db
version: '2'
services:
password:
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_ROOT_PASSWORD: password
のpassword
の部分がMySQLのパスワードになる。
##プロジェクトの作成
特に問題なくガイド通りに進められる。
databaseはMySQLなのでそこは変更する。
$ docker-compose run --rm web rails new . --force --database=mysql --skip-bundle
$ docker-compose build
##データベースに接続
###config/database.ymlを編集
password
を環境変数から取得するように変更。
host
をdb
にする。
default: &default
adapter: mysql2
encoding: utf8
pool: 5
username: root
password: <%= ENV['MYSQL_ROOT_PASSWORD'] %>
host: db
development:
<<: *default
database: myapp_development
test:
<<: *default
database: myapp_test
##データベース作成
up
が出来たのを確認したらそのまま落としても問題ないです。
$ docker-compose up
$ <ctrl-C>
$ docker-compose run --rm web rake db:create
##アプリ作成
本当にDBと連携して動いているのか確認するために簡単にアプリを作ってみる。
###みんな大好きscaffold
docker-compose up
は-d
オプションが良いと思う
$ docker-compose down
$ docker-compose run --rm web rails g scaffold item name:string amount:integer memo:text
$ docker-compose run --rm web rake db:migrate
$ docker-compose up -d
これで http://localhost:3000/items にアクセスして弄れることを確認。
docker-compose down
docker-compose up
を繰り返しても問題ないことを確認。
docker-compose up
したままviewやcontrolerを弄ってもブラウザ上に反映されることを確認。
#Nginxも含めた環境づくり
また今度、暇になったら記事にしてみたい。
#もやもやポイントまとめ
##docker-composeコマンド編
###サービス起動したら裏に回ってくれ。
docker-compose up -d
にする。
###サービス終了はどうするの?
docker-compose down
する。
docker-compose up
で回していたらCtrl+Cで強制終了。
##MySQL編
###対話的に設定したい
イメージ単独では何故か出来ません。
いや、対話用のMySQLクライアント作れば行けるのだろうが、railsコマンドで十分でしょ。
rootユーザーで操作しているのが気になるけど、どうやって対話以外でユーザー作成するのかわからんし。
rails dbconsole
があったか。
早速、
ん?rootがフルオープンだぞ?
ってことは開発機からもアクセスできるんじゃない?
出来た。
dockerのnetworkの外からアクセスさせたくない時は下のports
を消せばdocker内のrails以外からはアクセス出来なくなる。
version: '2'
services:
db:
ports:
- "3306:3306"
###dbのデータってどこにあるの?
mysqlのイメージ内で勝手にdockerディレクトリに永続化されているので、以下の設定を追加して開発ディレクトリ内に持ってくる。
services:
db:
volumes:
- ./docker/mysql/volumes:/var/lib/mysql
###dbのパスワードって?
以下のように書くとrootのパスワードを設定できる。
services:
db:
environment:
MYSQL_ROOT_PASSWORD: passward
ただしdocker-compose.ymlにMySQLのパスワードを直接書きたくないのでextends
を使って、以下のようにパスワードファイルに追い出す。
ついでにrails環境にもパスワードを渡す。
services:
db:
extends:
file: ./docker/mysql/password.yml
service: password
web:
extends:
file: ./docker/mysql/password.yml
service: password
version: '2'
services:
password:
environment:
MYSQL_ROOT_PASSWORD: password
これでpassword.ymlを.gitignoreで除外すればオールクリア。
##Rails編
###web_consoleが使えない
railsアプリに以下を追加。
config.web_console.automount = true
config.web_console.whitelisted_ips = %w( 0.0.0.0/0 ::/0 )
#最後に
今までVirtualBoxを使っていたけど、dockerは一度設定した後は手軽かも。
最初は設定・設定・また設定でうんざりしたけど、よく考えたらプロビジョニングとそんなに変わらんなぁと。
多分VirtualBoxには戻らない気がする。