docker-composeの勉強に,Railsの環境構築をやってみたのでハマったところも含めてメモ.
参考: Quickstart: Compose and Rails
実行環境
- MacBook Pro (13-inch, 2019)
- macOS Catalina version 10.15
- Docker version 19.03.5
- docker-compose version 1.24.1
- ruby 2.5.7
- Rails 5.2.4.1
- postgres (PostgreSQL) 12.2
構築手順
Dockerfileの作成
参考ページそのままに,Dockerfile
を作成.
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
COPY entrypoint.sh /usr/bin
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
Gemfileの作成
同じくGemfile
を作成.
source 'https://rubygems.org'
gem 'rails', '~>5'
Gemfile.lockの作成
空のGemfile.lock
を作成.
$ touch Gemfile.lock
entrypoint scriptの作成
server.pid
が存在するとサーバの再起動が失敗するというRails特有の問題があり,それを修正するためのentrypoint scriptを作成.
#!/bin/bash
set -e
rm -f /myapp/tmp/pids/server.pid
exec "$@"
docker-compose.ymlの作成
DBサーバとAPPサーバを立てるためのdocker-compose.yml
を作成.拡張子はyml
とyaml
のどちらでも大丈夫.
なお,参考ページに沿った手順で進めていますが,以下のdocker-compose.yaml
はDBのパスワードの設定が不足しているため注意(後述).
version: '3'
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
Railsアプリの作成
以下のコマンドを実行し,Railsアプリのスケルトンを作成.
$ docker-compose run web rails new . --force --no-deps --database=postgresql
DBの指定
Railsはデフォルトでlocalhost上で起動しているデータベースを探すので,dbコンテナを使うようconfig/database.yml
を以下の内容に置き換えます.
なお,先程のdocker-compose.yml
と同じく,DBのパスワードの設定が不足しています(後述).
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
すると,以下のエラーが表示されてdbコンテナが落ちます(本来ならDBの接続待ちのメッセージが表示される).
db_1 | Error: Database is uninitialized and superuser password is not specified.
db_1 | You must specify POSTGRES_PASSWORD to a non-empty value for the
db_1 | superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run".
db_1 |
db_1 | You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all
db_1 | connections without a password. This is not recommended.
postgresでパスワード無しでのログインが拒否されているため,config/database.yml
にパスワードを追記.
さらにdocker-compose.yml
にもパスワードを追記.
default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
password: postgres # ここを追記
pool: 5
development:
<<: *default
database: myapp_development
test:
<<: *default
database: myapp_test
version: '3'
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
environment: # ここから以下2行を追記
POSTGRES_PASSWORD: postgres
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
一旦落ちたdbコンテナも含めて削除し,再度docker-compose up
を実行.
$ docker-compose stop
$ docker rm $(docker ps -aq)
$ docker-compose up
すると,今度はdbコンテナのログでdatabase system is ready to accept connections
というメッセージが確認できます.
データベースの作成
最後に,以下のコマンドでデータベースを作成します.
$ docker-compose run web rake db:create
Starting ror_db_1 ... done
Created database 'myapp_development'
Created database 'myapp_test'
完成
これで全ての設定が完了したので,localhost:3000
にアクセスするとRailsの初期ページが表示されます.