はじめに
対象者:
- dockerは使ったことあるけど自分で構築した経験がない
-
クィックスタート: Compose と Railsは出来たから
既存のRailsプロジェクトをDocker化したい
ゴール:
- 既存のRailsプロジェクトを
docker compose up -d
だけで
Rails + DBが立ち上がる環境の構築
までを解説したいと思います。
前提
- Docker, Docker Composeのインストールが済んでいること
- 既存のRailsプロジェクトがあること
- クィックスタート: Compose と Railsを参考に既存のアプリをDocker化していきます。
手順
- dockerfileの作成
- compose.ymlの作成(docker-compose.ymlは非推奨となっています)
- database.ymlの修正
の順番で進めていきます。
1. dockerfileの作成
まず、Rubyを使えるコンテナを作成していきます。
既存のRubyプロジェクトのルートにDockerfileを作成していきます。
クィックスタート: Compose と RailsのDockercfileを借りてきます。
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
クィックスタートのDockerfileはそのまま使えないので少し修正していきます。
- バージョンを既存プロジェクトと一致するように
- RUN mkdir /myappを削除
- 既存プロジェクトのgemfileを使うように
- ローカルのプロジェクト自体をコンテナにコピー
以下が、修正後のDockerfileです。
FROM ruby:3.2.2
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
WORKDIR /myapp
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . ./
修正内容を見ていきます。
-
FROM ruby:3.2.2
バージョンの修正
こちらはご自身のRailsプロジェクトのバージョンと同じにしてください。 -
WORKDIR /myapp
コンテナで作業するディレクトリを指定します。
この時、指定の/myappがない場合はディレクトリを作成してくれるので
RUN mkdir /myapp
を削除しています。 -
COPY Gemfile Gemfile.lock ./
既存プロジェクトのgemfileを使うように
ローカルのPCにあるGemfile Gemfile.lock
をコンテナの./
のディレクトリにコピーします。
※./
は省略すると現在の作業ディレクトリにCOPYされます。今回はWORKDIR /myapp
を指定しているので省略しても/myapp
にコピーされます。
ローカルのPCにあるファイルをコンテナにコピーします。
.
とはdockerfileがあるディレクトリのことです。
./
とはコンテナのディレクトリのことです。今回の場合はWORKDIR /myapp
で指定したディレクトリですね。
ここで疑問に思う方もいるかもしれません。
COPY Gemfile Gemfile.lock ./
とCOPY . ./
分ける必要ないじゃん!
そうです、一緒にしてもいいです。
ただ、こればDockerのキャッシュを効率的に使うために分けています。
結論から言うと
Gemfile
Gemfile.lock
に変更がない場合はRUN bundle install
はスキップされます。
前回のCOPY Gemfile Gemfile.lock ./
でキャッシュされた結果が再利用され、その後のRUN bundle install
もキャッシュを利用します。
つまり、COPY . ./
だけにしてしまうと、プロジェクトのファイルに変更があるたびにRUN bundle install
が再実行される可能性が高くなります。
2. compose.ymlの作成
最終的なコードはこちらです。
services:
web:
build: .
command: bash -c "rails db:create db:migrate && rails s -p 3000 -b '0.0.0.0'"
ports:
- "3000:3000"
volumes:
- .:/myapp
depends_on:
- db
db:
image: postgres:12
environment:
POSTGRES_PASSWORD: postgres
ports:
- "5432:5432"
services:
-
web
-
build: .
:ホストのカレントディレクトリにあるDockerfileを使用して、webサービスのイメージをビルドします。 -
command
: コンテナ起動時に実行するコマンドを指定しています。ここでは、データベースの作成とマイグレーションを行った後、Railsサーバーを起動します。 -
ports
: ホストのポート3000をコンテナのポート3000にマッピングします。これにより、ホストのポート3000でRailsアプリケーションにアクセスできます。 -
volumes
: ホストのカレントディレクトリ(dockerfileがあるディレクトリ)をコンテナ内の/myappディレクトリにマウントします。これでホスト側のファイル変更がコンテナ内に反映されます。 -
depends_on
: webサービスはdbサービスに依存しており、dbサービスが起動してからwebサービスが起動します。
-
-
db
-
image
: postgres:12: PostgreSQLのバージョン12のイメージを使用します。 -
environment
: 環境変数を設定します。ここでは、PostgreSQLのパスワードを設定します。 -
ports
: ホストのポート5432をコンテナのポート5432にマッピングします。
-
version: '3'
の指定は非推奨になったので削除しています。
3. database.ymlの修正
最後にdatabase.ymlを修正していきます。
config/database.yml
にあると思います。
defaultの箇所を以下のように追加・修正します。
default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
password: postgres
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
-
default:
すべての環境で共通の設定を定義します。-
adapter
: 使用するデータベースの種類(ここではpostgresql)。 -
encoding
: データベースの文字エンコーディング(unicode)。 -
host
: データベースのホスト名(db、Docker Composeで定義されたサービス名)。 -
usernameとpassword
: Railsがデータベースに接続するためのユーザー名とパスワード。
-
以上で設定は終了です。
compose.ymlがあるディレクトリでdocker compose up -d
を実行して
localhost:3000
にアクセスしてみてください。
既存のRailsプロジェクトが表示されれば完了です。
データの永続化について
今回のサンプルではPostgreSQLデータベースのデータを永続化していません。
データの永続化にはDockerのボリュームを作成してそれをマウントする必要があります。
Dockerで作成したボリュームを、データを保存したいコンテナの特定のディレクトリにマウントします。
そうすることで、コンテナが停止したり削除された場合でも、データはボリュームに保存され続けます。
今回のサンプルでは紹介しませんが、気になる方は調べてやってみてください。