Dockerを触る機会ができたため、この機に勉強をしたいと思います。
DockerにはRailsプロジェクトを開始するチュートリアルがあったので、今回はそちらをやってみたいと思います。
今ではDockerもMacOSにインストールできるのですね。
まずはこちらからDocker for Macをインストールします。
特に変わった使い方をしたいわけではないので、Stable channel(安定版)を入手します。
基本的なコマンドはこちらで説明があります。
Get started with Docker for Mac
インストールしたDockerを起動し、下記コマンドで確認します。
$ 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
まずはディレクトリを作成します。
今回はdocker_railsという名前のプロジェクトにしたいと思います。
$ mkdir docker_rails $ cd docker_rails
Dockerイメージを作成するためのDockerfileをつくります。
今回はRubyの2.4.0を使用します。
FROM
でRubyのイメージから取得します。
DockerにあるRubyのイメージを見てみると、2.4.0があることが分かります。
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
RailsをロードするためのGemfileを作成します。
後ほど実施する`rails new`の際に書き換えられます。
今回のRailsは5.0.2を使用したいと思います。
source 'https://rubygems.org' gem 'rails', '5.0.2'
空のGemfile.lockを作成します。
Dockerをビルドする際に必要なようです。
$ touch Gemfile.lock
docker-composeは複数のコンテナを1つのyaml形式ファイルで管理できるようになります。
imageでもととなるDockerイメージを指定します。
Quickstart: Compose and RailsではデータベースにPostgreSQLを使用していますが、今回はMySQLを使用したいと思います。(このままではうまくいかないので、修正は後述します。)
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
ここまでで、4つのファイルができました。rails new
をして、プロジェクトを作成したいと思います。
データベースはMySQLにしたいので、--database
オプションはmysqlにします。
$ docker-compose run web rails new . --force --database=mysql --skip-bundle
このコマンド実行後、見慣れたRailsのフォルダ構成ができあがります。
Linux OS上にDockerを作成した場合はここでパーミッションの確認をするようですが、今回はMacなので省略します。
必要に応じてGemfileを修正し、ビルドします。
(ここではGemfileはデフォルトのままです。)
$ docker-compose build
データベースの接続設定をするため、database.ymlを修正します。
デフォルトだとプロジェクト名のデータベースが作成されます。
DockerコンテナのMySQLはlocalhostではないため、docker-compose.ymlでつけたサービス名で指定します。
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
すると、下記のようなエラーメッセージがでます。
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の方はチュートリアル通りになりましたが、データベースの方がエラーになっています。
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パスワードを設定していたような気がします。)
とりあえず、起動しているWebサーバーを`Ctrl + C`で停止します。
docker-compse.ymlで環境変数を設定することができます。
要求されているMYSQL_ROOT_PASSWORDを設定します。
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
または、
environment: MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
として、空のパスワードを許可します。
今回はrootパスワードを設定しました。
Railsのdatabase.ymlも修正します。
default: &default adapter: mysql2 encoding: utf8 pool: 5 username: root password: <%= ENV['MYSQL_ROOT_PASSWORD'] %> host: db
再度、`docker-compose up`をします。
時間がかかりますが起動しているはずです。
ただ、このままhttp://localhost:3000
にアクセスしてもデータベースが作成されていません。
そのため、ターミナルをもう1つ立ち上げ、マイグレーションを走らせます。
$ docker-compose run web rails db:create
これで`http://localhost:3000`にアクセスすればウェルカムページが表示されるはずです!
下記コマンドで起動しているコンテナの確認できます。
$ 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`で入ります。
$ docker exec -it dockerrails_db_1 sh
これでコンテナの中に入れます。
`dockerrails_db_1`の部分でコンテナを指定しています。
Railsのコンテナに入る場合も同様です。
# mysql --version mysql Ver 14.14 Distrib 5.7.17, for Linux (x86_64) using EditLine wrapper
チュートリアルの最後にも記載されておりますが、下記のようなエラーがでる場合があります。
web_1 | A server is already running. Check /myapp/tmp/pids/server.pid.
この場合はRailsの`tmp/pids/server.pid`を消せば良いようです。
私が使っていた感じですが、Dockerが落ちた後などに発生しているような気がしております。
そのため、終了する際は必ず`Ctrl + C`で消しておいた方が良さそうです。
DockerをGUIで操作できるツールです。
私も使っておりますが、`docker exec`などを使用できます。
記事としては、次回にしたいと思いますが、興味がある方はぜひ使ってみてください!