RailsアプリをDocker化する手順

Dockerの勉強をしたので、その復習として既存のRailsアプリをDocker化することにしました。

環境

Ruby: 3.2.2 Rails: 7.0.6 DB: PostgreSQL

手順

Dockerfileの作成

まずはイメージを作成するために必要なDockerfileを作成します。 今回Rubyのイメージを3.2.2と指定したところ、RUN apt-get ~の実行の際に 次のようなエラーが生じました。

生じたエラー

#5 0.903 Get:1 http://deb.debian.org/debian bookworm InRelease [151 kB]
#5 0.959 Get:2 http://deb.debian.org/debian bookworm-updates InRelease [52.1 kB]
#5 0.991 Get:3 http://deb.debian.org/debian-security bookworm-security InRelease [48.0 kB]
#5 1.032 Err:1 http://deb.debian.org/debian bookworm InRelease
#5 1.032   The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 0E98404D386FA1D9 NO_PUBKEY 6ED0E7B82643E131 NO_PUBKEY F8D2585B8783D481
#5 1.084 Err:2 http://deb.debian.org/debian bookworm-updates InRelease
#5 1.084   The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 0E98404D386FA1D9 NO_PUBKEY 6ED0E7B82643E131
#5 1.133 Err:3 http://deb.debian.org/debian-security bookworm-security InRelease
#5 1.133   The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 54404762BBB6E853 NO_PUBKEY BDE6D2B9216EC7A8
#5 1.135 Reading package lists...
#5 1.149 W: GPG error: http://deb.debian.org/debian bookworm InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 0E98404D386FA1D9 NO_PUBKEY 6ED0E7B82643E131 NO_PUBKEY F8D2585B8783D481
#5 1.149 E: The repository 'http://deb.debian.org/debian bookworm InRelease' is not signed.
#5 1.149 W: GPG error: http://deb.debian.org/debian bookworm-updates InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 0E98404D386FA1D9 NO_PUBKEY 6ED0E7B82643E131
#5 1.149 E: The repository 'http://deb.debian.org/debian bookworm-updates InRelease' is not signed.
#5 1.149 W: GPG error: http://deb.debian.org/debian-security bookworm-security InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 54404762BBB6E853 NO_PUBKEY BDE6D2B9216EC7A8
#5 1.149 E: The repository 'http://deb.debian.org/debian-security bookworm-security InRelease' is not signed.
#5 1.149 E: Problem executing scripts APT::Update::Post-Invoke 'rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true'
#5 1.149 E: Sub-process returned an error code
------
executor failed running [/bin/sh -c apt-get update && apt-get install -y     build-essential    libpq-dev    nodejs    postgresql-client    yarn]: exit code: 100

これに対する解決策としてRubyのイメージをbullseyeに変更しました。(Ruby参考記事)

Dockerfile

# apt-getのエラーを防ぐためにbullseyeイメージを使用
FROM ruby:3.2.2-bullseye
# 必要なパッケージをインストール
RUN apt-get update && apt-get install -y \
    build-essential\
    libpq-dev\
    nodejs\
    postgresql-client\
    yarn
# コンテナ内にホストと同じディレクトリを作成。
WORKDIR /rails-docker
COPY Gemfile Gemfile.lock /rails-docker/
RUN bundle install

docker-compose.ymlの作成

今回はRailsコンテナとDBコンテナを作成するため、docker composeを使用します。docker composeを使用することで、コンテナ起動時に長いコマンドを打ち込む必要がなくなり、複数コンテナを扱いやすくなります。 また、PostgreSQLイメージを12とするとDBコンテナが起動しないという事象が発生したため、DBイメージにはpostgres:12-bullseyeを使用しました。
PostgreSQL参考記事

docker-compose.yml

version: '3'

# ホストにボリューム領域を確保する
volumes:
  db-data:

services:
  web:
    build: .
 # コンテナ起動時にコマンドをこの実行
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
 # 使用するポート(Railsのデフォルトは3000)
    ports:
      - '3000:3000'
    volumes:
      - '.:/rails-docker'
 # database.ymlの環境変数を設定
    environment:
      - 'DATABASE_PASSWORD=postgres'
    tty: true
    stdin_open: true
 # dbコンテナ作成後にwebコンテナを作成する
    depends_on:
      - db
    links:
      - db

  db:
    image: postgres:12-bullseye
 # コンテナを削除してもデータが消えないように、ホストのファイルをコンテナにマウントする
    volumes:
      - 'db-data:/var/lib/postgresql/data'
 # 使用するデータベースの環境変数を設定
    environment:
      - 'POSTGRES_USER=postgres'
      - 'POSTGRES_PASSWORD=postgres'

database.yml

最後にDBの設定をファイルに記述していきます。

default: &default
  adapter: postgresql
  encoding: unicode
 # docker-compose.ymlのサービス名を指定する
  host: db
  user: postgres
 # PostgreSQLのデフォルトポートを指定
  port: 5432
 # docker-compose.ymlで指定した内容を読み取る
  password: <%= ENV.fetch("DATABASE_PASSWORD") %>
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

ビルド後、DBを作成

# コンテナを起動。再ビルド時には「--build」をつける
docker-compose up -d

# コンテナ内に入る
docker-compose exec web bash

#コンテナ内でDB作成
rails db:create

# データベースのテーブル定義を作成
rails db:migrate

# コンテナを抜ける
exit

# コンテナを再起動。「restart」でも可
docker-compose up

エラー無く実行ができれば完了

確認

localhost:3000にアクセスし、アプリのデータ登録を行う。その後、Ctr+Cでアプリを終了し、docker-compose upでコンテナを再起動させ、先程登録したデータが残っているかを確認する。

参考資料

クィックスタート: Compose と Rails
米国AI開発者がゼロから教えるDocker講座
php:8.2-fpmのdocker imageでapt-getしたらエラーが出まくった
PostgreSQL参考記事