はじめに
この記事では、 Rails アプリを Docker 環境で構築する手順についてまとめます。 作る環境は以下です。
- Ruby - 3.2.2
- Ruby on Rails - 7.0.8
- Postgres - 12
Rails アプリを Docker 化する手順
ローカルでの開発準備
今回は Desktop にrails-docker-app
という名前でディレクトリを作成します。(お好きな名前でどうぞ)
以降で Docker を使う上で必要なファイル等もこのタイミングで作っておきます。
cd ~/Desktop mkdir rails-docker-app && cd rails-docker-app touch Dockerfile docker-compose.yaml Gemfile Gemfile.lock
下記のディレクトリ構造になっていれば OK です。
rails-docker-app ├── Dockerfile ├── Gemfile ├── Gemfile.lock └── docker-compose.yaml
次に各ファイルの中身をつくっていきます。
Gemfile の作成
gem の取得先と rails のバージョンを記載しておきます。今回は7.0.6
を使います。
source 'https://rubygems.org' gem "rails", "~> 7.0.6"
Gemfile.lock の作成
こちらは中身は空のままで OK です。
Dockerfile の作成
まずは Rails(Web 側)の Dockerfile を作成していきます。
# ベースイメージの指定 FROM ruby:3.2.2 # 必要なパッケージのインストール RUN apt-get update -qq && apt-get install -y \ build-essential \ libpq-dev \ nodejs \ postgresql-client \ yarn # 作業ディレクトリの指定 WORKDIR /rails-docker-app # ホスト側のGemfile, Gemfile.lockをコンテナにコピー COPY Gemfile Gemfile.lock /rails-docker-app/ # Gemのインストール RUN bundle install
docker-compose.yaml の作成
docker-compose は、複数コンテナをまとめて起動したり、docker run
コマンドが長くなるときに便利です!
一旦、アプリ側のコンテナの設定を記載していきます。
version: "3" services: web: build: . ports: - "3000:3000" volumes: - ".:/rails-docker-app" tty: true stdin_open: true
ここからは、docker-compose up -d
でコンテナを起動後、
docker-compose web bash
でコンテナに入って作業していきます。
Rails アプリのセットアップ
rails new
コマンドでアプリの雛形を作成していきます。
今回は DB を使用するので--database=postgresql
で Postgres を指定します。
root@xxxxx:/rails-docker-app# rails new . --force --database=postgresql --skip-bundle
このコマンドを実行すると、rails で使用する gem がGemfile
に複数記載されるはずです。
これをインストールするためにはbundle install
を再実行する必要があるため、docker-compose down
で一度コンテナを抜けます。
Dockerfile の再ビルド
先程、rails new
で Gemfile が更新されたので、bundle install
を実行するために新しいイメージを作成する必要があります。古いイメージを使いたくないのでdocker-compose up --build -d
で新しいイメージでコンテナを起動するようにします。
コンテナ起動後、コンテナに入って rails サーバーを起動してみましょう。
root@xxxxxx:/rails-docker-app# rails s -b 0.0.0.0 => Booting Puma => Rails 7.0.8.3 application starting in development => Run `bin/rails server --help` for more startup options Puma starting in single mode... * Puma version: 5.6.8 (ruby 3.2.2-p53) ("Birdie's Version") * Min threads: 5 * Max threads: 5 * Environment: development * PID: 14 * Listening on http://0.0.0.0:3000 Use Ctrl-C to stop
しかし、データベースが作られていないことでエラー画面が表示されるはずです。 次はこちらを修正していきます。
config/database.yml に DB 情報追加
rails プロジェクト配下にあるconfig/database.yml
に下記のように追記します。
default: &default adapter: postgresql encoding: unicode ----- 👈 ここから host: db user: postgres port: 5432 password: postgres password: <%= ENV.fetch("DATABASE_PASSWORD")> ----- 👈 ここまで # For details on connection pooling, see Rails configuration guide # https://guides.rubyonrails.org/configuring.html#database-pooling pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> development: <<: *default database: rails_docker_app_development
次に docker-compose.yaml 側の修正も行っていきます。
docker-compose.yaml に DB 情報を追記
DB コンテナ用の定義を下記のように追記します。
version: "3" volumes: db-data: services: web: build: . ports: - "3000:3000" volumes: - ".:/rails-docker-app" environment: - "DATABASE_PASSWORD=postgres" tty: true stdin_open: true depends_on: - db links: - db db: image: postgres:12 environment: - "POSTGRES_USER=postgres" - "POSTGRES_PASSWORD=postgres" volumes: - "db-data:/var/lib/postgresql/data"
Rails アプリの DB セットアップ
docker-compose up -d
コマンドを実行して、Postgres のコンテナを起動します。この時点では web と db の2 種類のコンテナが起動しているはずです。
それではdocker-compose web bash
でコンテナに入って、rails db:create
コマンドを実行しましよう。
root@xxxxxxx:/rails-docker-app# rails db:create Created database 'rails_docker_app_development' Created database 'rails_docker_app_test'
rails g scaffold
でスキャフォールディングをします。
rails g scaffold product name:string price:integer vender:string
rails db:migrate
でマイグレーションを実行します。
root@xxxxxx:/rails-docker-app# rails db:migrate == 20240520141629 CreateProducts: migrating =================================== -- create_table(:products) -> 0.0048s == 20240520141629 CreateProducts: migrated (0.0049s) ==========================
Rails アプリのサーバー起動
ここまでできたらコンテナの中でrails s -b 0.0.0.0
を実行します。
ブラウザにアクセスすると、rails のマークが表示された画面が現れるはずです。
おわりに
ここまで読んでいただきありがとうございます! Docker を使うことでアプリと DB を組み合わせた環境構築を簡単に済ませられるので、とても便利だと感じるようになりました。 今回は Rails を例に説明しましたが、Node.js, Python など他にもいろんな技術スタックでもこれから試してみたいと思いました!