クィックスタート: Compose と Rails¶
このクィックスタートガイドでは Docker Compose を使って、簡単な Rails/PostgreSQL アプリを設定し実行する手順を示します。 はじめるには Compose のインストール が必要です。
プロジェクトの定義¶
アプリのビルドに必要となる 4 つのファイルを作るところから始めます。
まずアプリケーションは、その依存パッケージも含め、すべてを Docker コンテナの内部にて実行するようにします。
そこでコンテナ内に含めるものが何であるのかは、正確に定義する必要があります。
これを行うのが Dockerfile
というファイルです。
まずは Dockerfile を以下のようにします。
FROM ruby:2.3.3
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
ADD . /myapp
上の設定はイメージ内部にアプリケーション・コードを置きます。 そして Ruby、Bundler などの依存パッケージすべてをコンテナ内部においてビルドします。 Dockerfile の記述方法の詳細は Docker ユーザ・ガイド や Dockerfile リファレンス を参照してください。
次にブートストラップを行うファイル Gemfile
を生成して、Rails をロードできるようにします。
このファイルは rails new
を行ったタイミングで書き換わります。
source 'https://rubygems.org'
gem 'rails', '5.0.0.1'
空のファイル Gemfile.lock
を生成して Dockerfile
のビルドができるようにします。
touch Gemfile.lock
最後に docker-compose.yml
が取りまとめてくれます。
このファイルには、データベースとウェブという 2 つのアプリを含んだサービスが定義されています。
そしてそれぞれの Docker イメージをどう作るかが示されています。
(データベースは既存の PostgreSQL イメージにより動作します。
ウェブアプリはカレントディレクトリ内に生成されます。)
また、リンクによってそれを結び合わせることが設定されていて、ウェブ・アプリのポートは外部に公開されています。
version: '3'
services:
db:
image: postgres
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
ちなみに
このファイルの拡張子は .yml
と .yaml
のどちらでも構いません。
プロジェクトのビルド¶
ここまでの 4 つのファイルを使って docker-compose run を実行し、Rails アプリのひながたを生成します。
docker-compose run web rails new . --force --database=postgresql
最初に Compose は Dockerfile
を用いて web
サービスに対するイメージをビルドします。
そしてこのイメージを利用して、新たに生成されたコンテナ内にて rails new
を実行します。
処理が完了すれば、できたてのアプリが生成されているはずです。
ファイル一覧を見てみます。
$ ls -l
total 64
-rw-r--r-- 1 vmb staff 222 Jun 7 12:05 Dockerfile
-rw-r--r-- 1 vmb staff 1738 Jun 7 12:09 Gemfile
-rw-r--r-- 1 vmb staff 4297 Jun 7 12:09 Gemfile.lock
-rw-r--r-- 1 vmb staff 374 Jun 7 12:09 README.md
-rw-r--r-- 1 vmb staff 227 Jun 7 12:09 Rakefile
drwxr-xr-x 10 vmb staff 340 Jun 7 12:09 app
drwxr-xr-x 8 vmb staff 272 Jun 7 12:09 bin
drwxr-xr-x 14 vmb staff 476 Jun 7 12:09 config
-rw-r--r-- 1 vmb staff 130 Jun 7 12:09 config.ru
drwxr-xr-x 3 vmb staff 102 Jun 7 12:09 db
-rw-r--r-- 1 vmb staff 211 Jun 7 12:06 docker-compose.yml
drwxr-xr-x 4 vmb staff 136 Jun 7 12:09 lib
drwxr-xr-x 3 vmb staff 102 Jun 7 12:09 log
drwxr-xr-x 9 vmb staff 306 Jun 7 12:09 public
drwxr-xr-x 9 vmb staff 306 Jun 7 12:09 test
drwxr-xr-x 4 vmb staff 136 Jun 7 12:09 tmp
drwxr-xr-x 3 vmb staff 102 Jun 7 12:09 vendor
Linux 上で Docker を利用している場合、rails new
により生成されたファイルの所有者は root になります。
これはコンテナが root ユーザにより実行されているためです。
この場合は、生成されたファイルの所有者を以下のように変更してください。
sudo chown -R $USER:$USER .
Docker on Mac あるいは Docker on Windows を利用している場合、rails new
により生成されたファイルも含め、すべてのファイルに対しての所有権は、正しく設定されているはずです。
ここに新たな Gemfile が作成されたので、イメージを再ビルドすることが必要です。
(再ビルドが必要になるのは、今の時点、あるいは一般的には Gemfile
や Dockerfile を修正したときだけです。)
docker-compose build
データベースの接続設定¶
アプリは実行可能ですが、実行するのはまだです。
デフォルトで Rails は localhost
において実行されているデータベースを用います。
したがってここでは db
コンテナを用いるように書き換える必要があります。
また postgres
イメージにおいて設定されているデフォルトのデータベース名、ユーザ名を変更することも必要です。
config/database.yml
の記述内容を以下のように書き換えます。
default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
password:
pool: 5
development:
<<: *default
database: myapp_development
test:
<<: *default
database: myapp_test
docker-compose up によりアプリを起動します。
docker-compose up
正常に動作すれば、PostgreSQL による出力が確認できるはずです。 そしてすぐに、いつもの出力が続きます。
Starting rails_db_1 ...
Starting rails_db_1 ... done
Recreating rails_web_1 ...
Recreating rails_web_1 ... done
Attaching to rails_db_1, rails_web_1
db_1 | LOG: database system was shut down at 2017-06-07 19:12:02 UTC
db_1 | LOG: MultiXact member wraparound protections are now enabled
db_1 | LOG: database system is ready to accept connections
db_1 | LOG: autovacuum launcher started
web_1 | => Booting Puma
web_1 | => Rails 5.0.0.1 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.9.1 (ruby 2.3.3-p222), codename: Private Caller
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
最後にデータベースを生成することが必要です。 別の端末から以下を実行します。
docker-compose run web rake db:create
コマンドから出力される結果は、たとえば以下のようになります。
vmb at snapair in ~/sandbox/rails
$ docker-compose run web rake db:create
Starting rails_db_1 ... done
Created database 'myapp_development'
Created database 'myapp_test'
Rails の「ようこそ」ページの確認¶
以上です。 Docker デーモンを通じて、アプリがポート 3000 番を使って実行されています。
Docker Desktop for Mac や Docker Desktop for Windows の場合は、ウェブ・ブラウザから http://localhost:3000
にアクセスすれば Rails のようこそページを確認できます。
Docker Machine を利用している場合は、docker-machine ip MACHINE_VM
を実行すると Docker ホストの IP アドレスを得ることができます。
これにポート番号をつけて利用します。
(<Docker-Host-IP>:3000
)
アプリケーションの停止¶
アプリケーションを停止するには、プロジェクト・ディレクトリにおいて docker-compose down を実行します。 この場合に用いる端末画面は、データベースを起動したときと同じものを用いるか、あるいはコマンド・プロンプトにアクセスできる別画面であっても構いません。 これがアプリケーションを適切に停止する方法です。
vmb at snapair in ~/sandbox/rails
$ docker-compose down
Stopping rails_web_1 ... done
Stopping rails_db_1 ... done
Removing rails_web_run_1 ... done
Removing rails_web_1 ... done
Removing rails_db_1 ... done
Removing network rails_default
アプリケーションの停止はまた、docker-compose up
を実行したシェルにおいて Ctrl-C
を入力することでも実現できます。
ただしこの方法で停止した場合に、さらに再起動しようとすると、以下のようなエラーが発生するかもしません。
web_1 | A server is already
running. Check /myapp/tmp/pids/server.pid.
このエラーを解決するには、tmp/pids/server.pid
を削除してから、再び docker-compose up
を実行すれば、アプリケーションを再起動することができます。
アプリケーションの再起動¶
アプリケーションを再起動するには、以下を実行します。
- プロジェクト・ディレクトリにて
docker-compose up
を実行します。 - 以下のコマンドを別の端末から実行して、データベースを再起動します。
docker-compose run web rake db:create
アプリケーションの再ビルド¶
Gemfile や Compose ファイルを編集して、いろいろと別の設定とした場合には、再ビルドが必要になります。
変更内容によっては docker-compose up --build
だけで済む場合もあります。
しかし完全に再ビルドを行うには、docker-compose run web bundle install
を再度実行して、ホストにおける Gemfile.lock
の変更と同期を取ることが必要になります。
その後に docker-compose up --build
を実行します。
以下に示すのは前者、つまり完全な再ビルドは必要としない例です。
ローカルホスト側の公開ポートを 3000
から 3001
に変更する場合を取り上げます。
Compose ファイルにおいて、コンテナ側にて 3000
としているポートを新たなポート 3001
に変更します。
そしてこの変更を保存します。
ports: - "3001:3000"
再ビルドとアプリの再起動は docker-compose up --build
により行います。
そしてデータベースの再起動は docker-compose run web rake db:create
を実行します。
コンテナ内部において、アプリはそれまでと変わらないポート 3000
で稼動していますが、ローカルホスト上から Rails ようこそページにアクセスするのは http://localhost:3001
となります。