🦓

Docker Compose で Rails 7.x + Ruby 3.x + PostgreSQL環境構築

2023/07/22に公開

はじめに

Rails 7.1からDockerfileがデフォルトで含まれるようになったので、Dockerを使った環境構築を見ていきます。

Docker Composeを使用してRails 7.x、Ruby 3.x、PostgreSQLの環境を構築していきます。

ドキュメントを参考しながら進めていきます。
https://matsuand.github.io/docs.docker.jp.onthefly/samples/rails/

Docker Compose

Docker Composeは、Dockerを利用して複数のコンテナを組み合わせて複雑なアプリケーションの開発、テスト、デプロイを行うためのツールです。

Railsプロジェクトはホストのディレクトリとコンテナのディレクトリを共有しているため、ホストでファイルを編集してもコンテナ内のRailsサーバーに反映されます。また、PostgreSQLもDockerコンテナ内で動作しているため、Railsアプリケーションからデータベースにアクセスすることができます。

Docker Composeで実現したいこと:

  1. 環境の一貫性と再現性: Dockerを使用することで、開発、テスト、本番環境など、異なる環境間でアプリケーションが一貫した動作をすることができます。Dockerコンテナにはアプリケーションとその依存関係が含まれており、環境を再現するのに便利です。
  2. コンテナ間の依存関係の管理: Dockerを使用することで、複雑な環境構築や依存関係の管理をシンプルにすることができます。Dockerコンテナに必要な依存関係や設定を含めるため、新しい環境にアプリケーションを展開する際に手間が省けます。
  3. チームでの共同作業の向上: Dockerを使用することで、開発チームが共通の環境を持つことができます。これにより、アプリケーションのビルドやテスト、デプロイの際に生じる環境の違いによる問題を回避することができます。
  4. 一括起動・停止: 複数のコンテナを一括で起動、停止することができます。

手順

1. rails_app/ディレクトリを作成し、プロジェクトを定義するDockerfileを作成する
2. Railsのバージョンを指定するGemfileを作成する
3. 空のファイルGemfile.lockを生成してDockerfileのビルドができるようにする
4. docker-compose.ymlを作成する
5. データベースの設定を変更するためにconfig/database.ymlを編集する
6. コンテナをビルドしてサーバーを起動する

Dockerfile

Dockerコンテナのビルドに使用されるテキストファイルのことです。Dockerコンテナは、アプリケーションとその依存関係を含む軽量な仮想化単位であり、Dockerイメージとしてビルドされます。Dockerfileには、Dockerイメージを構築するための手順やコマンドが記述されています。

Dockerコマンドを使ってDockerfileをビルドすると、Dockerイメージが作成され、そのイメージを元にDockerコンテナを起動することができます。

Dockerfileのコマンド
  1. FROM: ベースイメージを指定します。Dockerコンテナはベースイメージから始まり、その上にアプリケーションや依存関係が追加されます。一般的なベースイメージには、公式のDocker Hubから提供されるOS(例:Ubuntu、Alpine)、プログラム言語(例:Ruby、Python)、Webサーバー(例:Nginx、Apache)などがあります。

  2. RUN: Dockerコンテナ内で実行するコマンドを指定します。このコマンドは、Dockerイメージをビルドする際に実行され、その結果がコンテナに反映されます。例えば、必要なパッケージのインストール、アプリケーションのビルド、ファイルのコピーなどが含まれます。

  3. COPYまたはADD: ホストマシンのファイルをDockerコンテナ内にコピーします。COPYは単純なファイルコピーに使用され、ADDはアーカイブの解凍やURLからのファイル取得など、より高度な機能を持ちます。

  4. WORKDIR: コンテナ内の作業ディレクトリを指定します。以降のコマンドはこのディレクトリを基準に実行されます。

  5. EXPOSE: コンテナが使用するポート番号を指定します。ただし、ポートの公開はdocker runコマンドの際に-pオプションで行う必要があります。

  6. CMDまたはENTRYPOINT: コンテナが起動した際に実行されるコマンドを指定します。CMDはデフォルトのコマンドを上書きできますが、ENTRYPOINTは上書きできません。

公式のrubyイメージ:
https://hub.docker.com/_/ruby

Dockerfile
# イメージ
# アプリのrubyバージョンを指定する
FROM ruby:3.2.1

# インストールするdependencies
RUN apt-get update -qq && \
    apt-get install -y build-essential libvips && \
    postgresql-client\
    file\
    imagemagick\
    git\
    tzdata\
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man

# ディレクトリを作成する
WORKDIR /rails_app

# 環境変数の設定(ここでは本番環境)
ENV RAILS_LOG_TO_STDOUT="1" \
    RAILS_SERVE_STATIC_FILES="true" \
    RAILS_ENV="production" \
    BUNDLE_WITHOUT="development"

# gemのインストール
COPY Gemfile Gemfile.lock ./
RUN bundle install

# カレントディレクトリにあるファイルやディレクトリをDockerコンテナ内の作業ディレクトリ(/rails_app)にコピーする
COPY . .

# bootsnapプリーコンパイル
RUN bundle exec bootsnap precompile --gemfile rails_app/ lib/

# アセッのプリーコンパイル
RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile

# 起動スクリプト(あれば)
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

# ポート番号の設定
EXPOSE 3000
CMD ["./bin/rails", "server"]
dependenciesをインストールする

RUN apt-get update -qq && \: apt-getコマンドを使用して、ディストリビューションのパッケージリストを更新します。-qqオプションは、出力を最小限に抑えるための静かなモードを指定しています。

Alpine Linuxのパッケージマネージャーであるapkを使用してパッケージをインストールしています。また、不要なキャッシュファイルを削除してイメージサイズを小さくしています。

postgresql-client: PostgreSQLのクライアントツールをインストールします。これは、Dockerコンテナ内でPostgreSQLデータベースにアクセスするために必要です。

file: ファイルコマンドをインストールします。このコマンドはファイルの種類を判定するために使用されます。

imagemagick: ImageMagickをインストールします。ImageMagickは画像の処理や変換などに使用されるツールです。

git: Gitをインストールします。これにより、Dockerコンテナ内でGitリポジトリを管理することができます。

tzdata: タイムゾーン情報を設定するためのパッケージです。

&& rm -rf /var/cache/apk/* /var/lib/apt/lists/* /usr/share/doc /usr/share/man: 不要なパッケージキャッシュやインストールされたパッケージのリスト、ドキュメントなどを削除します。これにより、Dockerイメージのサイズを小さくし、不要なファイルを含まないようにします。

環境変数を設定する
  1. RAILS_LOG_TO_STDOUT="1": Railsアプリケーションのログを標準出力に出力するかどうかを設定します。この値が"1"の場合、Railsのログは標準出力に出力され、Dockerのログドライバーによってログが収集されます。docker logsでログを見ることができます

  2. RAILS_SERVE_STATIC_FILES="true": 静的ファイル(CSS、JavaScript、画像など)をRailsアプリケーション内でサーバーから直接提供するかどうかを設定します。この値が"true"の場合、静的ファイルがRailsアプリケーションのWebサーバーから直接提供されます。Railsから提供しないことによってアプリのパフォーマンスの向上につながります。

  3. RAILS_ENV="production": Railsアプリケーションが動作する環境を指定します(config/environments/production.rb.)。この場合、Railsアプリケーションは本番環境で実行されます。環境によって設定されるデータベース接続情報やアセットのコンパイル方法などが異なります。

  4. BUNDLE_WITHOUT="development": バンドル(Gem)のインストール時に、指定されたグループ(development、testなど)を無視してインストールするかどうかを設定します。この場合、developmentグループに含まれるGemはインストールされず、本番環境向けのGemだけがインストールされます。

Bootsnapのプリーコンパイル

RUN bundle exec bootsnap precompile --gemfile rails_app/ lib/ は、Dockerイメージのビルド時にRailsアプリケーションに対してBootsnapのプリーコンパイルを実行するコマンドです。

Bootsnapは、Railsの起動時間を高速化するために使用されるGemで、一度ロードされたコードをキャッシュして再利用することで起動時間を削減します。bundle exec bootsnap precompileコマンドは、Bootsnapのキャッシュを事前に生成するために実行されます。キャッシュが生成されることで、アプリケーションの起動時間が短縮されるため、本番環境でのパフォーマンスが向上します。

具体的には、--gemfile rails_app/ lib/の部分は、プレコンパイルの対象となるGemfileのパスを指定しています。この場合、RailsアプリケーションのGemfileがrails_app/ディレクトリにあると想定されていますが、実際のディレクトリ構造に応じて適切なパスを指定する必要があります。

このコマンドはDockerfile内でRUNコマンドとして実行されるため、Dockerイメージのビルド時にBootsnapのプリーコンパイルが行われます。ビルドされたDockerイメージは、起動時にキャッシュを利用することで高速化されたRailsアプリケーションを実行することができます。

アセットのプリーコンパイル

RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile は、Dockerイメージのビルド時にRailsアプリケーションのアセットをプリコンパイルするコマンドです。

  1. SECRET_KEY_BASE_DUMMY=1: Railsアプリケーションでは、セッションやクッキーを暗号化するための秘密鍵としてSECRET_KEY_BASEという環境変数が必要です。ただし、Dockerビルド時には本物のSECRET_KEY_BASEがまだ利用できないため、ダミーの値を設定してプリコンパイルを実行します。実際の運用時には正しいSECRET_KEY_BASEを設定する必要があります。

  2. bundle exec: bundle execを付けることで、Gemfileに指定されたバンドルされたGemを使用してRailsアプリケーションのコマンドを実行します。これにより、アプリケーションで指定されたバージョンのGemを使ってコマンドが実行されます。

  3. rails assets:precompile: Railsアプリケーションのアセット(CSS、JavaScript、画像など)をプリコンパイルします。これにより、アセットのコンパイル済みバージョンが生成され、本番環境でのパフォーマンスが向上します。

このコマンドはDockerfile内でRUNコマンドとして実行されるため、Dockerイメージのビルド時にアセットのプリコンパイルが行われます。ビルドされたDockerイメージは、Railsアプリケーションを実行する際に事前にプリコンパイルされたアセットを利用することで、起動時間やパフォーマンスの向上を実現します。

特定の起動スクリプト

ENTRYPOINT ["/rails/bin/docker-entrypoint"] は、Dockerコンテナが起動された際に実行されるエントリーポイント(起動スクリプト)を設定するコマンドです。

Dockerコンテナは、起動時に実行されるコマンドを指定することができます。通常、CMDRUNコマンドを使用して、アプリケーションを起動するコマンドを指定しますが、ENTRYPOINTを使用することで、Dockerコンテナが常に特定のスクリプトを実行するように設定することができます。

具体的には、ENTRYPOINT ["/rails/bin/docker-entrypoint"]は、Dockerコンテナが起動されるときに/rails/bin/docker-entrypointというパスにあるスクリプトを実行するように設定しています。このスクリプトは、RailsアプリケーションのDockerコンテナの起動時に特定のタスクを実行したり、環境変数の設定などを行ったりする役割を持っていることが想定されています。

エントリーポイントのスクリプトの例:

entrypoint.sh
#!/bin/bash

# If running the rails server then create or migrate existing database
if [ "${*}" == "./bin/rails server" ]; then
  ./bin/rails db:prepare
fi

exec "${@}"
  1. #!/bin/bash: シェルスクリプトであることを示すシバン(shebang)です。このスクリプトは/bin/bashシェルで実行されることを指定しています。

  2. if [ "${*}" == "./bin/rails server" ]; then: 引数をチェックして、もし./bin/rails serverがコマンドとして指定されている場合に以下の処理を行います。

  3. ./bin/rails db:prepare: Railsアプリケーションのデータベースを作成またはマイグレーションを実行するためのdb:prepareタスクを実行します。これにより、Dockerコンテナが起動したときにデータベースが正しく設定されます。

  4. exec "${@}": 最後に、指定された引数を実行します。これにより、Dockerコンテナが実際に指定されたコマンド(例:./bin/rails server)を実行することになります。

このスクリプトの目的は、特定の条件でRailsアプリケーションのデータベースをセットアップすることです。通常、RailsアプリケーションのデータベースをDockerコンテナ内で適切に設定するためには、データベースの作成やマイグレーションが必要です。
このスクリプトはそれを自動化しており、RailsアプリケーションがDockerコンテナ内で起動される際にデータベースを準備するためのスクリプトです。

ポート番号の設定

EXPOSE 3000 は、Dockerコンテナが公開するポート番号を設定するコマンドです。ここでは、3000番ポートをDockerコンテナの外部に公開するように指定しています。この設定により、ホストからDockerコンテナ内のRailsアプリケーションに接続することができます。

CMD ["./bin/rails", "server"] は、Dockerコンテナが起動された際に実行されるデフォルトのコマンドを設定するコマンドです。ここでは、Railsアプリケーションを起動するためのデフォルトのコマンドを指定しています。

docker build -t rails_app .
docker run -p 3000:3000 rails_app

これにより、ホストのポート3000にDockerコンテナのポート3000がマッピングされ、RailsアプリケーションがWebサーバーとして実行されることになります。

Gemfile

Gemfileを作成し、railsのバージョンを指定します。
既存のRailsアプリを使う場合はこのステップは不要となります。

Gemfile
# source "https://rubygems.org"
gem "rails", "~> 7.0.4", ">= 7.0.4.3"

Gemfile.lock

空のファイルGemfile.lockを生成してDockerfileのビルドができるようにします。
既存のRailsアプリを使う場合はこのステップは不要となります。

touch Gemfile.lock

docker-compose.yml

docker-compose.ymlというファイルにアプリケーションのコンテナ構成や設定を記述し、docker-composeコマンドを使用してアプリケーションを管理します。このファイルには、各サービスのイメージ名、ポートのマッピング、ボリュームの設定、環境変数の指定などが含まれます。

docker-compose.yml
version: "3.9"
services:
  db:
    image: postgres
    restart: always
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
      TZ: "Asia/Tokyo"
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/rails_app
    ports:
      - "3000:3000"
    depends_on:
      - db

PostgreSQLデータベースコンテナとRailsアプリケーションコンテナの2つのサービスを定義しています。

  1. version: "3.9": Docker Composeのバージョンを指定しています。3.9は、Composeファイルのバージョンを示しています。

db: PostgreSQLデータベースサービスを定義しています。

  • image: postgres: Dockerイメージとして公式のPostgreSQLイメージを使用しています。
  • volumes: ホストの./tmp/dbディレクトリとPostgreSQLコンテナの/var/lib/postgresql/dataディレクトリを永続化ボリュームとしてマウントしています。これにより、データベースのデータがホストに保存され、コンテナの停止・再起動時でもデータが保持されます。
  • environment: 環境変数を設定しています。ここでは、POSTGRES_PASSWORDpasswordを設定しています。これは、PostgreSQLデータベースの管理者パスワードです。
  1. web: Railsアプリケーションサービスを定義しています。
  • build: .: ホストのカレントディレクトリにあるDockerfileを使用して、カスタムのRailsアプリケーションイメージをビルドします。
  • command: アプリケーションの起動コマンドを設定しています。ここでは、Railsサーバーを起動する前にtmp/pids/server.pidファイルを削除してから、bundle exec rails sコマンドでRailsサーバーをバインドアドレス0.0.0.0とポート3000で起動しています。
  • volumes: ホストのカレントディレクトリとDockerコンテナ内の/rails_appディレクトリをマウントしています。これにより、ホストマシンのコードがコンテナ内で利用できるようになります。
  • ports: ホストマシンのポート3000をコンテナのポート3000にマッピングしています。これにより、ホストマシンからRailsアプリケーションにアクセスできます。
  • depends_on: dbサービスに依存しています。これにより、データベースコンテナが起動してからアプリケーションコンテナが起動するようになります。

postgresの設定について公式のイメージを参考にしてみてください。
https://hub.docker.com/_/postgres

https://matsuand.github.io/docs.docker.jp.onthefly/samples/rails/#connect-the-database

データベースの接続設定

デフォルトで Rails はlocalhostにおいて実行されているデータベースを用います。 したがってここではdbコンテナーを用いるように書き換える必要があります。 またpostgresイメージにおいて設定されているデフォルトのデータベース名、ユーザー名を変更することも必要です。

config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: 
  password: password
  pool: 5

development:
  <<: *default
  database: rails_app_development


test:
  <<: *default
  database: rails_app_test

production:
  <<: *default
  database: rails_app_production
  username: <%= ENV['POSTGRES_USERNAME'] %>
  password: <%= ENV['POSTGRES_PASWSWORD'] %>
  host: <%= ENV['POSTGRES_HOST'] %>

.envフィルにDBの情報を入れていきます。
ファイルの設定が完了しました。

イメージをビルドする

# 新規のrailsアプリを作成してビルドする
docker-compose run --no-deps web rails new . --force --database=postgresql

# 既存のアプリを現在のディレクトリでビルドする
docker build --tag rails_app .
docker build -t rails_app .

[+] Building 74.7s (13/13) FINISHED                                                                                                           
 => [internal] load .dockerignore                                                                                                        0.0s
 => => transferring context: 2B                                                                                                          0.0s
 => [internal] load build definition from Dockerfile                                                                                     0.0s
 => => transferring dockerfile: 1.14kB                                                                                                   0.0s
 => [internal] load metadata for docker.io/library/ruby:3.2.1                                                                            1.8s
 => [1/8] FROM docker.io/library/ruby:3.2.1@sha256:b38264d66820f3696906ed5fa51b1317d83215515f4a45500c9bf403bf2c9b47                     23.2s
 => => resolve docker.io/library/ruby:3.2.1@sha256:b38264d66820f3696906ed5fa51b1317d83215515f4a45500c9bf403bf2c9b47                      0.0s
 => => sha256:070703b8ae4c26e61b7939940ca1d7ade4943f2cb51633526ee034b6d3a9515f 2.00kB / 2.00kB                                           0.0s
 => => sha256:3440a912810a14b912ef9738d7b50bb95673c60cd2af71b16b8ace9730723a76 8.42kB / 8.42kB                                           0.0s
 => => sha256:3e440a7045683e27f8e2fa04000e0e078d8dfac0c971358ae0f8c65c13321c8e 55.05MB / 55.05MB                                         1.5s
 => => sha256:b38264d66820f3696906ed5fa51b1317d83215515f4a45500c9bf403bf2c9b47 1.86kB / 1.86kB                                           0.0s
 => => sha256:68a71c865a2c34678c6dea55e4b0928f751ee3c0ca91cace6e4e0578c534d6cf 5.17MB / 5.17MB                                           0.3s
 => => sha256:670730c27c2eacf07897a6e94fe55423ea50b884d9c28161a283bbbf064d1124 10.88MB / 10.88MB                                         0.6s
 => => sha256:5a7a2c95f0f8b221d776ccf35911b68eec2cf9414a44d216205a6f03e381d3d7 54.58MB / 54.58MB                                         1.7s
 => => sha256:6d627e120214bb28a729d4b54a0ecba4c4aeaf0295ca2d1f129480145fad2af6 196.81MB / 196.81MB                                       4.9s
 => => extracting sha256:3e440a7045683e27f8e2fa04000e0e078d8dfac0c971358ae0f8c65c13321c8e                                                4.6s
 => => sha256:adce7d0cf0c9443924156ba59b5cee73e9679ade2301baf4172114bbc7d237a9 198B / 198B                                               1.7s
 => => sha256:f83e8ed56f1de2e661614b9f47540f0fc8024b6c1ce36243377cac32c638756f 34.55MB / 34.55MB                                         2.3s
 => => sha256:f6a7165b526d74dd846e912b33629aa91a8ee907ecec6208171b4ad59bc9b4d1 175B / 175B                                               1.9s
 => => extracting sha256:68a71c865a2c34678c6dea55e4b0928f751ee3c0ca91cace6e4e0578c534d6cf                                                0.4s
 => => extracting sha256:670730c27c2eacf07897a6e94fe55423ea50b884d9c28161a283bbbf064d1124                                                0.3s
 => => extracting sha256:5a7a2c95f0f8b221d776ccf35911b68eec2cf9414a44d216205a6f03e381d3d7                                                3.9s
 => => extracting sha256:6d627e120214bb28a729d4b54a0ecba4c4aeaf0295ca2d1f129480145fad2af6                                               10.1s
 => => extracting sha256:adce7d0cf0c9443924156ba59b5cee73e9679ade2301baf4172114bbc7d237a9                                                0.0s
 => => extracting sha256:f83e8ed56f1de2e661614b9f47540f0fc8024b6c1ce36243377cac32c638756f                                                1.7s
 => => extracting sha256:f6a7165b526d74dd846e912b33629aa91a8ee907ecec6208171b4ad59bc9b4d1                                                0.0s
 => [internal] load build context                                                                                                        0.3s
 => => transferring context: 253.97kB                                                                                                    0.3s
 => [2/8] RUN apt-get update -qq &&     apt-get install -y build-essential libvips    postgresql-client    file    imagemagick    git   25.2s
 => [3/8] WORKDIR /rails_app                                                                                                            0.0s
 => [4/8] COPY Gemfile Gemfile.lock ./                                                                                                   0.0s
 => [5/8] RUN bundle install                                                                                                            15.6s
 => [6/8] COPY . .                                                                                                                       0.3s 
 => [7/8] RUN bundle exec bootsnap precompile --gemfile rails_app/ lib/                                                                 1.3s 
 => [8/8] RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile                                                                4.9s 
 => exporting to image                                                                                                                   2.3s 
 => => exporting layers                                                                                                                  2.3s 
 => => writing image sha256:18e4953d4be12ffa02f612c0160ba0f7dba4e3aa8276a4f3e378cff1b610fd1e                                             0.0s 
 => => naming to docker.io/library/rails_app                                                                                            0.0s 

コンテナをビルド・起動

docker-composeでrailsサーバー、DBサーバー、他のアプリケーションサーバーを一括で起動します。

docker-compose up
[+] Running 14/14
 ✔ db 13 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                  12.9s 
   ✔ faef57eae888 Pull complete                                                                                                          3.7s 
   ✔ a33c10a72186 Pull complete                                                                                                          3.7s 
   ✔ d662a43776d2 Pull complete                                                                                                          3.9s 
   ✔ a3ba86413420 Pull complete                                                                                                          4.0s 
   ✔ a627f37e9916 Pull complete                                                                                                          4.5s 
   ✔ 424bade69494 Pull complete                                                                                                          4.6s 
   ✔ dd8d4fcd466b Pull complete                                                                                                          4.7s 
   ✔ 03d0efeea592 Pull complete                                                                                                          4.7s 
   ✔ 4f27e1518a67 Pull complete                                                                                                          9.3s 
   ✔ 0c8ac8b8eb90 Pull complete                                                                                                          9.3s 
   ✔ c08e79653ad2 Pull complete                                                                                                          9.3s 
   ✔ d5724e8c22af Pull complete                                                                                                          9.3s 
   ✔ 3db4aa0d2013 Pull complete                                                                                                          9.3s 
[+] Building 3.8s (14/14) FINISHED           
...
[+] Building 0.0s (0/0)                                                                                                                       
[+] Running 3/3
 ✔ Network rails_app_default  Created                                                                                                   0.1s 
 ✔ Container rails_app-db-1   Created                                                                                                   0.1s 
 ✔ Container rails_app-web-1  Created                                                                                                   0.1s 
Attaching to rails_app-db-1, rails_app-web-1
rails_app-db-1   | 
rails_app-db-1   | PostgreSQL Database directory appears to contain a database; Skipping initialization
rails_app-db-1   | 
rails_app-db-1   | 2023-07-22 01:11:17.759 JST [1] LOG:  starting PostgreSQL 15.3 (Debian 15.3-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
rails_app-db-1   | 2023-07-22 01:11:17.760 JST [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
rails_app-db-1   | 2023-07-22 01:11:17.760 JST [1] LOG:  listening on IPv6 address "::", port 5432
rails_app-db-1   | 2023-07-22 01:11:17.770 JST [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
rails_app-db-1   | 2023-07-22 01:11:17.808 JST [30] LOG:  database system was shut down at 2023-07-22 01:10:42 JST
rails_app-db-1   | 2023-07-22 01:11:17.879 JST [1] LOG:  database system is ready to accept connections
rails_app-web-1  | => Booting Puma
rails_app-web-1  | => Rails 7.0.6 application starting in production 
rails_app-web-1  | => Run `bin/rails server --help` for more startup options
rails_app-web-1  | Puma starting in single mode...
rails_app-web-1  | * Puma version: 5.6.6 (ruby 3.2.1-p31) ("Birdie's Version")
rails_app-web-1  | *  Min threads: 5
rails_app-web-1  | *  Max threads: 5
rails_app-web-1  | *  Environment: production
rails_app-web-1  | *          PID: 1
rails_app-web-1  | * Listening on http://0.0.0.0:3000
rails_app-web-1  | Use Ctrl-C to stop

DBを作成する

docker-compose run web rails db:create

[+] Building 0.0s (0/0)                                                                                     
[+] Creating 1/0
 ✔ Container rails_app-db-1  Created                                                                  0.0s 
[+] Running 1/1
 ✔ Container rails_app-db-1  Started                                                                  0.2s 
[+] Building 0.0s (0/0)                                                                                     
Created database 'rails_app_production'

DBをマイグレートする

既存のアプリをビルドする場合DBのマイグレーションもしましょう。

docker-compose run web rails db:migrate

[+] Building 0.0s (0/0)                                                                                                       
[+] Creating 1/0
 ✔ Container rails_app-db-1  Created                                                                                    0.0s 
[+] Running 1/1
 ✔ Container rails_app-db-1  Started                                                                                    0.2s 
[+] Building 0.0s (0/0)                                                                                                       
I, [2023-07-22T03:37:47.133244 #1]  INFO -- : Migrating to DeviseCreateUsers (20230717085247)
== 20230717085247 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0431s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0074s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.0081s
== 20230717085247 DeviseCreateUsers: migrated (0.0590s) =======================

I, [2023-07-22T03:37:47.241297 #1]  INFO -- : Migrating to CreateBlogs (20230717086604)
== 20230717086604 CreateBlogs: migrating ======================================
-- create_table(:blogs)
   -> 0.0468s
== 20230717086604 CreateBlogs: migrated (0.0469s) =============================

アセットをコンパイルする

docker-compose run web rake assets:precompile

[+] Building 0.0s (0/0)                                                              
[+] Creating 1/0
 ✔ Container rails_app-db-1  Created                                           0.0s 
[+] Running 1/1
 ✔ Container rails_app-db-1  Started                                           0.2s 
[+] Building 0.0s (0/0)                                                              

Rebuilding...

Done in 1136ms.
...

docker-compose upでサーバーを起動する

docker-compose up
[+] Building 0.0s (0/0)                                                                                      
[+] Running 2/0
 ✔ Container rails_app-db-1   Running                                                                  0.0s 
 ✔ Container rails_app-web-1  Created                                                                  0.0s 
Attaching to rails_app-db-1, rails_app-web-1
rails_app-web-1  | => Booting Puma
rails_app-web-1  | => Rails 7.0.6 application starting in production 
rails_app-web-1  | => Run `bin/rails server --help` for more startup options
rails_app-web-1  | Puma starting in single mode...
rails_app-web-1  | * Puma version: 5.6.6 (ruby 3.2.1-p31) ("Birdie's Version")
rails_app-web-1  | *  Min threads: 5
rails_app-web-1  | *  Max threads: 5
rails_app-web-1  | *  Environment: production
rails_app-web-1  | *          PID: 1
rails_app-web-1  | * Listening on http://0.0.0.0:3000
rails_app-web-1  | Use Ctrl-C to stop
rails_app-web-1  | I, [2023-07-22T03:44:33.481569 #1]  INFO -- : [b0c2d45a-c058-48eb-84c5-eef2cf165ae4] Started GET "/" for 172.20.0.1 at 2023-07-22 03:44:33 +0000
rails_app-web-1  | I, [2023-07-22T03:44:33.486321 #1]  INFO -- : [b0c2d45a-c058-48eb-84c5-eef2cf165ae4] Processing by BlogsController#index as HTML
rails_app-web-1  | I, [2023-07-22T03:44:33.684520 #1]  INFO -- : [b0c2d45a-c058-48eb-84c5-eef2cf165ae4]   Rendered blogs/index.html.erb within layouts/application (Duration: 184.7ms | Allocations: 4867)
rails_app-web-1  | I, [2023-07-22T03:44:33.705586 #1]  INFO -- : [b0c2d45a-c058-48eb-84c5-eef2cf165ae4]   Rendered layout layouts/application.html.erb (Duration: 205.8ms | Allocations: 8962)
rails_app-web-1  | I, [2023-07-22T03:44:33.705893 #1]  INFO -- : [b0c2d45a-c058-48eb-84c5-eef2cf165ae4] Completed 200 OK in 219ms (Views: 211.9ms | ActiveRecord: 141.0ms | Allocations: 10635)
rails_app-db-1   | 2023-07-22 12:46:39.292 JST [28] LOG:  checkpoint starting: time
rails_app-db-1   | 2023-07-22 12:46:39.853 JST [28] LOG:  checkpoint complete: wrote 8 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.529 s, sync=0.003 s, total=0.561 s; sync files=4, longest=0.002 s, average=0.001 s; distance=0 kB, estimate=0 kB

無事に環境構築できました。

基本操作

イメージのビルド

Dockerイメージをビルドしますが、実際にコンテナを作成・起動はしません。

# 複数のDockerイメージを一括してビルドする
docker-compose build

単一のDockerイメージをビルドする
docker build

イメージの起動

docker run rails_app

# ポート番号を指定する
docker run -p 3000:3000 rails_app

コンテナの作成と起動(railsとdb)

docker-compose.ymlを読み込んでコンテナを作成・起動します。

docker-compose up -d

コンテナの停止と削除

docker-compose down

コンテナ一覧

docker-compose ps

# 現在実行中のDockerコンテナを表示する
docker ps

# すべてのDockerコンテナ(実行中と停止中)を表示する
docker ps -a

ログの表示

docker-compose logs

Discussion