DockerでRails6+PostgreSQLの開発環境を構築する
バージョン
- Ruby 2.7.5
- Rails 6.1.5 (※APIモードではなく通常モード)
- PostgreSQL 14.2
rails newで除外するもの
自分にとって不要なものを外す
- turbolinks
- test (RSpecを後で使う予定なので、minitestは不要)
- actioncable
gemのインストール先
公式のRubyイメージではbundle installのインストール先が/usr/local/bundleになっている。
それを前提としてbundle installはオプションをつけずに実行する。
また、docker-comopse buildの時間を短縮するため、/usr/local/bundleをボリュームとして保持する。
ボリューム
以下についてはすべてボリュームに保存する事にして
Railsプロジェクト直下には置かないことにする。
- PostgreSQLのdataディレクトリ
- vender/bundle
- node_modules
1. 作業用ディレクトリの作成
railsプロジェクトのルートとなるディレクトリを作成。
$ mkdir rails-app
$ cd rails-app
2. GemfileとGemfile.lockを作成する
$ touch Gemfile
$ touch Gemfile.lock
Gemfileには使用したいRailsのバージョンだけを記述。
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem "rails", "6.1.5"
3. Dockerfileを作成する
FROM ruby:2.7.5
RUN apt-get update -qq && apt-get install -y build-essential postgresql-client
WORKDIR /myapp
# install nodejs(LTS)
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - && apt-get install -y nodejs
# npm自体のバージョンを最新にする
RUN npm install -g npm
# install yarn
RUN npm install -g yarn
# gem
COPY Gemfile /myapp/
COPY Gemfile.lock /myapp/
RUN gem install bundler
RUN bundle install
# コンテナー起動時に毎回実行されるスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
# 3000番ポートをリンクしたサービスのみに公開
EXPOSE 3000
4. entrypoint.shを作成する
#!/bin/bash
set -e
# server.pidが残っているとrailsが起動できないので削除する
rm -f /myapp/tmp/pids/server.pid
# コンテナーのプロセスを実行する(Dockerfile 内の CMD に設定されているもの)
exec "$@"
5. docker-compose.ymlを作成
version: "3.9"
services:
db:
image: postgres:14.2
container_name: rails-app_db
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_USER: devuser
POSTGRES_PASSWORD: devuser
POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=C"
networks:
- mynetwork
web:
image: rails-app_web
build:
context: .
dockerfile: Dockerfile
container_name: rails-app_web
command: bash -c "bundle install && yarn install --check-files && rm -f tmp/pids/server.pid && bundle exec pumactl start"
environment:
TZ: Asia/Tokyo
RAILS_ENV: development
volumes:
- .:/myapp
- bundle:/usr/local/bundle
- node_modules:/myapp/node_modules
ports:
- "3000:3000"
depends_on:
- db
networks:
- mynetwork
networks:
mynetwork:
name: rails-app
volumes:
pgdata:
name: rails-app_pgdata
bundle:
name: rails-app_bundle
node_modules:
name: rails-app_node_modules
Gitでファイルを管理する
あとでやり直せるように、gitで管理しておく。
$ git init
$ git add -A
$ git commit -m "initial commit"
6. Railsプロジェクトを作成する
rails newの時に、bundle installやyarn installをするとエラーになるので後で行う事にする(--skip-bundle --skip-webpack-install)。
後は、turbolinks、actioncable、testを除外するオプションを指定して実行。
$ docker-compose run web rails new . --force --no-deps --database=postgresql \
--skip-action-cable --skip-turbolinks --skip-test \
--skip-bundle --skip-webpack-install
成功すると、カレントディレクトリにrailsプロジェクトのファイルが生成されている。
この時に、Gemfileも上書きされる。
ファイルのパーミッションはrootになっているので、現在操作しているユーザーに変更しておく。
$ sudo chown -R ${USER}:${USER} .
Gemfileをシンプルにする
コメントが多くてごちゃごちゃしているので自分はいつもコメントを消してバージョン指定も最小限にする。
pgのバージョンを指定しているのは、1.3に上げるとなにかの警告が表示されたため。
本来はここからrspec-railsやkaminariなどを追加していくのだが、とりあえず最小限の状態にしておく。
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.7.5'
gem 'rails', '~> 6.1.5'
gem 'pg', '~> 1.2.3'
gem 'puma'
gem 'sass-rails'
gem 'webpacker'
gem 'jbuilder'
gem 'bcrypt'
gem 'bootsnap', require: false
gem 'tzinfo-data'
group :development do
gem 'web-console'
gem 'listen'
gem 'spring'
end
ここまでの作業をコミット
$ git add -A
$ git commit -m "railsプロジェクトを作成"
7. Dockerイメージをビルド
$ docker-compose build
8. DB接続設定を修正
config/database.ymlをdocker-compose.ymlの内容に合わせて修正する。
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
port: 5432
host: db
username: devuser
password: devuser
development:
<<: *default
database: myapp_dev
test:
<<: *default
database: myapp_test
production:
<<: *default
database: myapp_production
username: <%= ENV["DATABASE_USERNAME"] %>
password: <%= ENV["DATABASE_PASSWORD"] %>
host: <%= ENV["DATABASE_HOST"] %>
9. bundle installを行う
$ docker-compose run web bundle install
10. webpacker:installを行う
$ docker-compose run web bin/rails webpacker:install
11. データベースを作成
$ docker-compose run web bin/rails db:create
うまく行くと、このような表示になる。
[+] Running 3/1
⠿ Network rails-app Created 0.1s
⠿ Volume "rails-app_pgdata" Created 0.0s
⠿ Container rails-app_db Created 0.0s
[+] Running 1/1
⠿ Container rails-app_db Started 0.4s
Running via Spring preloader in process 20
Created database 'myapp_dev'
Created database 'myapp_test'
12. コンテナを起動
$ docker-compose up
成功すると以下のようなログが流れる。
rails-app_web | => Booting Puma
rails-app_web | => Rails 6.1.5 application starting in development
rails-app_web | => Run `bin/rails server --help` for more startup options
rails-app_web | Puma starting in single mode...
rails-app_web | * Puma version: 5.6.4 (ruby 2.7.5-p203) ("Birdie's Version")
rails-app_web | * Min threads: 5
rails-app_web | * Max threads: 5
rails-app_web | * Environment: development
rails-app_web | * PID: 1
rails-app_web | * Listening on http://0.0.0.0:3000
rails-app_web | Use Ctrl-C to stop
ブラウザで http://localhost:3000/ にアクセスしてRailsのトップページが表示されたら成功。
Discussion