はじめに
Dockerを触る機会ができたため、この機に勉強をしたいと思います。
DockerにはRailsプロジェクトを開始するチュートリアルがあったので、今回はそちらをやってみたいと思います。
環境
- Mac OS X Yosemite 10.10.5
Docker for Macのインストール
今ではDockerもMacOSにインストールできるのですね。
まずはこちらからDocker for Macをインストールします。
特に変わった使い方をしたいわけではないので、Stable channel(安定版)を入手します。
基本的なコマンドはこちらで説明があります。
Get started with Docker for Mac
インストールしたDockerを起動し、下記コマンドで確認します。
1 2 3 4 5 6 | $ docker --version Docker version 17.03.0-ce, build 60ccb22 $ docker-compose --version docker-compose version 1.11.2, build dfed245 $ docker-machine --version docker-machine version 0.10.0, build 76ed2a6 |
Railsプロジェクトを作成するまで
Railsのプロジェクトディレクトリの作成
まずはディレクトリを作成します。
今回はdocker_railsという名前のプロジェクトにしたいと思います。
1 2 | $ mkdir docker_rails $ cd docker_rails |
Dockerfileの作成
Dockerイメージを作成するためのDockerfileをつくります。
今回はRubyの2.4.0を使用します。
FROM
でRubyのイメージから取得します。
DockerにあるRubyのイメージを見てみると、2.4.0があることが分かります。
1 2 3 4 5 6 7 8 | FROM ruby:2.4.0 RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs RUN mkdir /docker_rails WORKDIR /docker_rails ADD Gemfile /docker_rails/Gemfile ADD Gemfile.lock /docker_rails/Gemfile.lock RUN bundle install ADD . /docker_rails |
Gemfileの作成
RailsをロードするためのGemfileを作成します。
後ほど実施する
rails new
の際に書き換えられます。
今回のRailsは5.0.2を使用したいと思います。
1 2 | source 'https://rubygems.org' gem 'rails', '5.0.2' |
Gemfile.lockの作成
空のGemfile.lockを作成します。
Dockerをビルドする際に必要なようです。
1 | $ touch Gemfile.lock |
docker-compose.ymlの作成
docker-composeは複数のコンテナを1つのyaml形式ファイルで管理できるようになります。
imageでもととなるDockerイメージを指定します。
Quickstart: Compose and RailsではデータベースにPostgreSQLを使用していますが、今回はMySQLを使用したいと思います。(このままではうまくいかないので、修正は後述します。)
1 2 3 4 5 6 7 8 9 10 11 12 13 | version: '2' services: db: image: mysql web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/docker_rails ports: - "3000:3000" depends_on: - db |
Railsプロジェクトの作成
ここまでで、4つのファイルができました。
rails new
をして、プロジェクトを作成したいと思います。
データベースはMySQLにしたいので、
--database
オプションはmysqlにします。
1 | $ docker-compose run web rails new . --force --database=mysql --skip-bundle |
このコマンド実行後、見慣れたRailsのフォルダ構成ができあがります。
docker-compose build
Linux OS上にDockerを作成した場合はここでパーミッションの確認をするようですが、今回はMacなので省略します。
必要に応じてGemfileを修正し、ビルドします。
(ここではGemfileはデフォルトのままです。)
1 | $ docker-compose build |
Railsのdatabase.ymlを修正
データベースの接続設定をするため、database.ymlを修正します。
デフォルトだとプロジェクト名のデータベースが作成されます。
DockerコンテナのMySQLはlocalhostではないため、docker-compose.ymlでつけたサービス名で指定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | default: &default adapter: mysql2 encoding: utf8 pool: 5 username: root password: host: db development: <<: *default database: docker_rails_development test: <<: *default database: docker_rails_test production: <<: *default database: docker_rails_production username: docker_rails password: <%= ENV['DOCKER_RAILS_DATABASE_PASSWORD'] %> |
docker-compose up
それでは起動させてみます。
1 | $ docker-compose up |
すると、下記のようなエラーメッセージがでます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Starting dockerrails_db_1 Creating dockerrails_web_1 Attaching to dockerrails_db_1, dockerrails_web_1 db_1 | error: database is uninitialized and password option is not specified db_1 | You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD dockerrails_db_1 exited with code 1 web_1 | => Booting Puma web_1 | => Rails 5.0.2 application starting in development on http://0.0.0.0:3000 web_1 | => Run `rails server -h` for more startup options web_1 | Puma starting in single mode... web_1 | * Version 3.8.1 (ruby 2.4.0-p0), codename: Sassy Salamander web_1 | * Min threads: 5, max threads: 5 web_1 | * Environment: development web_1 | * Listening on tcp://0.0.0.0:3000 web_1 | Use Ctrl-C to stop |
webの方はチュートリアル通りになりましたが、データベースの方がエラーになっています。
1 2 3 | db_1 | error: database is uninitialized and password option is not specified db_1 | You need to specify one of MYSQL_ROOT_PASSWORD, MYSQL_ALLOW_EMPTY_PASSWORD and MYSQL_RANDOM_ROOT_PASSWORD dockerrails_db_1 exited with code 1 |
パスワードが設定されていないためにエラーになっているようです。
(確かにMySQLを普通にたてるとき、はじめにrootパスワードを設定していたような気がします。)
MySQLのrootパスワードを設定
とりあえず、起動しているWebサーバーを
Ctrl + C
で停止します。
docker-compse.ymlで環境変数を設定することができます。
要求されているMYSQL_ROOT_PASSWORDを設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | version: '2' services: db: image: mysql environment: MYSQL_ROOT_PASSWORD: root web: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/docker_rails ports: - "3000:3000" depends_on: - db |
または、
1 2 | environment: MYSQL_ALLOW_EMPTY_PASSWORD: "yes" |
として、空のパスワードを許可します。
今回はrootパスワードを設定しました。
Railsのdatabase.ymlも修正します。
1 2 3 4 5 6 7 | default: &default adapter: mysql2 encoding: utf8 pool: 5 username: root password: <%= ENV['MYSQL_ROOT_PASSWORD'] %> host: db |
再度、docker-compose up
再度、
docker-compose up
をします。
時間がかかりますが起動しているはずです。
ただ、このまま
http://localhost:3000
にアクセスしてもデータベースが作成されていません。
そのため、ターミナルをもう1つ立ち上げ、マイグレーションを走らせます。
1 | $ docker-compose run web rails db:create |
これで
http://localhost:3000
にアクセスすればウェルカムページが表示されるはずです!
起動しているコンテナの確認
下記コマンドで起動しているコンテナの確認できます。
1 2 3 4 | $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 590076cec87b dockerrails_web "bundle exec rails..." 10 minutes ago Up 10 minutes 0.0.0.0:3000->3000/tcp dockerrails_web_1 487c642a5f47 mysql "docker-entrypoint..." 15 minutes ago Up 10 minutes 3306/tcp dockerrails_db_1 |
一番右のNAMESがコンテナの名前です。
試しにMySQLコンテナに入って、MySQLのバージョンを確認してみます。
docker exec -it
で入ります。
1 | $ docker exec -it dockerrails_db_1 sh |
これでコンテナの中に入れます。
dockerrails_db_1
の部分でコンテナを指定しています。
Railsのコンテナに入る場合も同様です。
1 2 | # mysql --version mysql Ver 14.14 Distrib 5.7.17, for Linux (x86_64) using EditLine wrapper |
さいごに
「A server is already running.」というエラーが出た場合
チュートリアルの最後にも記載されておりますが、下記のようなエラーがでる場合があります。
1 | web_1 | A server is already running. Check /myapp/tmp/pids/server.pid. |
この場合はRailsの
tmp/pids/server.pid
を消せば良いようです。
私が使っていた感じですが、Dockerが落ちた後などに発生しているような気がしております。
そのため、終了する際は必ず
Ctrl + C
で消しておいた方が良さそうです。
Kitematicについて
DockerをGUIで操作できるツールです。
私も使っておりますが、
docker exec
などを使用できます。
記事としては、次回にしたいと思いますが、興味がある方はぜひ使ってみてください!