Docker compose で rails6 の環境構築
docker の公式と Qiita などの参考を参考に、一からアプリを docker 上で立ち上げてみた。
なお、環境は rails6, DB は postgresql で設定。
1. 必要ファイルの作成
まず最初に、アプリを作成するディレクトリを作成し、そのディレクトリに移動する。
$ mkdir myapp $ cd myapp
アプリのルートディレクトリ上で5つのファイルを作成する。
- Dockerfile
- Gemfile
- Gemfile.lock
- entrypoint.sh
- docker-compose.yml
以下、各々のファイルについて抜粋して説明。
Doclerfile
FROM ruby:2.6.5 RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list RUN apt-get update -qq && apt-get install -y \ build-essential \ libpq-dev \ nodejs \ vim \ yarn \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* RUN mkdir /myapp WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install COPY . /myapp # Add a script to be executed every time the container starts. COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] EXPOSE 3000 # Start the main process. CMD ["rails", "server", "-b", "0.0.0.0"]
curl コマンドで yarn のパッケージを呼び出しているのは、rails6 の webpacker に必要なため。
パッケージをインストールするときは、apt-get update と apt-get install を1行にまとめる。
行をまとめることで古いパッケージ情報のキャッシュ利用を避けることができる。
オプション -qq は、エラー以外は表示しない。 -y は、すべての問い合わせに yes と答えるという意味。
インストールするパッケージは、アルファベット順になっていると良い。
今回使用しなかったが、--no-install-recommends オプションを使って必要最小限のインストールを一度に複数行うことができるらしい。
apt-get clean でキャッシュをクリーンにし、 /var/lib/apt/lits を削除することで、イメージのサイズを減らすことができる。
docker の公式では -qq がついているけど、ベストプラクティスでは -qq がついていない。どちらが良いのだろうか?-qq は冗長だという記事も散見された。
Doclerfile, Demfile.rock
source 'https://rubygems.org' gem 'rails', '~>6'
公式のまま。(バージョンは rail6 に置き換え)
Gemfileの内容は、後でrails newをすると書き換えられるので、とりあえず rails だけで良い。
Gemfile.rockは空で良い。
entrypoint.sh
#!/bin/bash set -e # Remove a potentially pre-existing server.pid for Rails. rm -f /myapp/tmp/pids/server.pid # Then exec the container's main process (what's set as CMD in the Dockerfile). exec "$@"
公式のまま。
set -e はエラーが発生するとスクリプトを終了するオプション
rm -f で前のサーバーが立ち上げたまま終了してしまった場合に残るファイルを削除。
exec "$@" でCMDで渡されたコマンドを実行しています。(rails server)
docker-compose.yml
version: '3' services: db: image: postgres volumes: - pgdata:/var/lib/postgresql/data environment: 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
公式のまま。
[version] docker-composeのバージョン。現在の最新は3。
[services] この下のハッシュにサービスを作りましょう。なんでも良いですが通常はwebとdbと名付けます。
2. アプリの作成とビルド
docker 上で rails new してアプリ作成
$ docker-compose run web rails new . --force --no-deps --database=postgresql --skip-test --webpacker
- force ファイルが存在する場合、上書き。
- no-deps リンクしたサービスを起動しない設定。
- database=postgresql rails のデフォルトは sqlite3 のため、postgresqlを指定。
- skip-test RSpec導入のため、minitest(テストディレクトリの作成)をスキップする
- webpacker rails6対応。webpackerをインストールする。
rails関連ファイルができて、webpackerのインストールに成功したら、イメージをビルドする。
$ docker-compose build
3. データベースの作成と接続
rails new で作成された config/database.yml を編集して、接続先を修正。
# config/database.yml default: &default adapter: postgresql encoding: unicode host: db username: postgres password: postgres pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
docker 上でデータベースを作成する
$ docker-compose run web rake db:create
特に、Dockerfile のベストプラクティスは Dockerfile で何をしているのかよくわかったので勉強になった。
次回は、作ったDockerfile に Entrykit を導入すると便利そうなので、追加してみたいと思う。
参考記事
Quickstart: Compose and Rails | Docker Documentation
Dockerfile のベストプラクティス — Docker-docs-ja 1.9.0b ドキュメント
Dockerfile に apt, apt-get, source コマンドを書く時のTips | cloud.config Tech Blog
MacにDocker+Rails6+MySQLで開発環境構築 - Qiita
DockerでRuby on Railsの環境構築を行うためのステップ【Rails 6対応】 - Qiita
Dockerを使ってRails6環境の構築をしてみる - Qiita
DockerでのRuby on Rails環境構築を一つずつ詳解する - Qiita