はじめに
Dockerの学習として既存のRailsアプリの環境構築を行ったため、作業内容をまとめます。
開発環境
下記を使用して環境構築を行いました。
- Mac(M1 chip)
- Ruby 3.0.2
- postgres 12.0
- node 12.4
- yarn 1.16.0
フォルダ構成
既存のアプリのフォルダ内にDockerfile
、docker-compose.yml
、空のファイルであるGemfile.lock
を追加しました。
/rails-docker
├─app
├─bin
├─config
│ └─database.yml
├─db
├─lib
├─log
├─public
├─storage
├─test
├─tmp
├─vendor
├─babel.config.js
├─config.ru
├─Gemfile
├─Gemfile.lock
├─package.json
├─postcss.config.js
├─Rakefile
├─README.md
├─yarn.lock
├─Dockerfile
└─docker-compose.yml
Dockerfileの作成
Dockerfile
の入力内容です。
ポイントは以下の2点です。
・nodeをマルチステージビルドを利用してインストールをしている。
・package.json
とyarn.lock
を追加している。
FROM node:12.4-stretch as node
FROM ruby:3.0.2
RUN apt-get update -qq && apt-get install -y \
build-essential \
libpq-dev
ENV YARN_VERSION 1.16.0
RUN mkdir -p /opt
COPY --from=node /opt/yarn-v$YARN_VERSION /opt/yarn
COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
&& ln -s /opt/yarn/bin/yarn /usr/local/bin/yarnpkg \
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs \
&& ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
&& ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock
RUN gem install bundler
RUN bundle install
ADD package.json yarn.lock /myapp/
RUN yarn install
COPY . /myapp
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
マルチステージビルドとは
マルチステージビルドとは、アプリを効率的にビルドするための手法です。
FROM行が複数あることが特徴です。
マルチステージビルドを使用するメリットはイメージサイズが軽量化できることです。
不要なプログラムをインストールせず、必要なファイルのみを抽出することにより、イメージサイズを小さくすることができます。
(今回の例で説明すると、Railsアプリを起動するために必要なnode,yarnのファイルを抽出しています。)
Dockerfileでpackage.jsonとyarn.lockを追加する理由
Dockerfile
内でpackage.json
とyarn.lock
を追加している理由は、アプリ起動時にWebpacker::Manifest::MissingEntryErrorのエラーを解消するためです。
Dockerfile
内でyarn install
を実行する場合、その時点で存在するpackage.json
とyarn.lock
に基づいて依存関係がインストールされるのですが、その時コンテナが完全では無い為(ファイルが未完成であったり、コード自体がまだコンテナにコピーされていなかったり)依存関係の解決が正しく行われず、エラーが発生します。
ちなみに、Dockerfile
内にpackage.json
、yarn.lock
、yarn install
を入力せず、コンテナ内でyarn install
を実行する方法でも、その時点で存在する完全なpackage.json
とyarn.lock
に基づいて依存関係がインストールされるので依存関係のエラーは出ないです。
docker-compose.ymlの作成
docker-composeを使用することで、ターミナルで入力するDockerコマンドを簡潔なコマンドで実行できるようになります。
docker-compose.yml
の入力内容です。
version: '3'
services:
db:
image: postgres
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: postgres
volumes:
- .:/dbapp
web:
build: .
command: bundle exec rails s -p 3000 -b '0.0.0.0'
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
volumes:
- .:/webapp
ports:
- "3000:3000"
depends_on:
- db
database.ymlの修正
database.yml
の入力内容です。
adapter
をpostgresql
に変更しています。
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
host: db
username: postgres
password: password
development:
<<: *default
database: db/development
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: db/test
production:
<<: *default
database: db/production
Gemfileへの追記
postgresqlを使うために必要なgemとして、Gemfile
にpg
を追加しています。
gem 'pg'
Railsアプリの起動方法
1.コンテナの起動
docker-compose up
2.ターミナルの新規タブを開き、ファイルが保存されているディレクトリへ移動
3.データベースを作成
docker-compose run web rake db:create
4.コンテナの中に入る
docker-compose exec web bash
5.データベースにテーブルを作成
rails db:migrate
6.ブラウザを開き、URLを入力
http://localhost:3000/
アプリが実行できれば成功です。