React フロントエンド アプリケーションを使用して Ruby on Rails を Docker 化すると、開発ワークフローとデプロイメント プロセスが大幅に改善されます。アプリの標準化された環境を作成することで、開発、テスト、運用のさまざまな段階、さらには異なるシステム間でも一貫した動作が保証されます。実際、システムの違いに関連する問題を最小限に抑えるように設計されています。このガイドでは、Rails および React アプリを Docker コンテナーでスムーズに実行するための重要な手順について説明します。
Docker は、開発者のマシン、テスト環境、実稼働サーバーなど、どこにデプロイされてもアプリケーションが同じように実行されることを保証します。この一貫性は、すべての依存関係と構成をコンテナ化することで実現されます。
Docker コンテナには、アプリケーションを実行するために必要なすべての依存関係が含まれています。つまり、システム ライブラリのバリエーションや、異なるシステムでの依存関係の欠落がアプリケーションの機能に影響を与えることはありません。
Docker コンテナは、互いに、またホスト システムから分離して実行されます。この分離により、同じシステム上の異なるアプリケーションとそれらの依存関係間の競合が防止されます。
注意: Docker構文の知識が必要です
Docker 化には、イメージとコンテナという 2 つの重要な概念が関係します。イメージはコンテナの設計図として機能し、依存関係やデプロイメント構成など、コンテナを作成するために必要なすべての情報が含まれています。コンテナはイメージのランタイム インスタンスであり、イメージ自体、実行環境、およびランタイム命令で構成されます。一般的に、Docker はソフトウェアの出荷の標準を確立します。
Docker を簡単な例えで説明すると、コンテナを庭にある輸送コンテナ、イメージをコンテナ内に置かれたアイテム、輸送船をコンテナが実行されるシステムと考えてください。
アプリケーションをセットアップしてビルドするときは常に、特定の環境設定が必要です。たとえば、システムに Ruby 環境がインストールされていないと、Rails アプリケーションを実行することはできません。同様に、 Node.js
がないと React アプリケーションを実行できず、 npm
やYarn
などの Node パッケージ マネージャーがないと React パッケージをインストールできません。
コンテナはユーザーのシステムから独立して実行されるため、システム上に直接構築した場合と同じように、これらすべてのパッケージをコンテナ内で利用できるようにします。これにより、コンテナは仮想マシンのように独自のシステムとして機能します。Docker と仮想マシンには違いがありますが、この例はさらに説明するためのものです。
それでは、Rails アプリケーションを Docker 化してみましょう。これを行うには、Rails アプリケーションにDockerfile
、 docker-compose.yml
、 bin/docker-entrypoint
3 つのファイルが必要になります。これらの各ファイルを詳しく見ていきましょう。
注意: Docker構文の知識が必要です
Dockerfile
、Docker コンテナを作成するための設計図です。Docker がイメージを構築するために使用する一連の命令が含まれており、そのイメージを使用してコンテナを実行できます。Ruby on Rails および React アプリケーションのDockerfile
詳しく見てみましょう。
ARG RUBY_VERSION=3.1.4 FROM ruby:$RUBY_VERSION
ARG RUBY_VERSION=3.1.4
: RUBY_VERSION
という名前のビルド引数を定義します。デフォルト値は3.1.4
です。これはビルド時に上書きできます。
FROM ruby:$RUBY_VERSION
: RUBY_VERSION
で指定されたバージョンのruby
ベースイメージを使用します。これにより、コンテナが Ruby ランタイムでセットアップされます。前述したように、Rails アプリケーションを実行するには、Ruby がインストールされている必要があります。RUN apt-get update -qq && \ apt-get install -y build-essential libvips bash bash-completion libffi-dev tzdata postgresql curl && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man
apt-get update -qq
: リポジトリからパッケージ リストを更新します。 -qq
を指定すると出力は静かになります。
apt-get install -y
... : さまざまなパッケージをインストールします: build-essential
: ソフトウェアをビルドするための必須パッケージ (GCC など)。
libvips
: 画像処理用のライブラリ。
bash
、 bash-completion
: Bash シェルとその自動補完。
libffi-dev
: 外部関数インターフェースライブラリ。
tzdata
: タイムゾーンデータ。
postgresql
: PostgreSQL データベース クライアント。
curl
: URL からデータを転送するためのツール。
apt-get clean
: 取得したパッケージ ファイルのローカル リポジトリをクリーンアップします。
rm -rf /var/lib/apt/lists/ /usr/share/doc /usr/share/man
: イメージのサイズを縮小するためにパッケージ リストとドキュメントを削除します。RUN curl -fsSL https://deb.nodesource.com/setup_current.x | bash - && \ apt-get install -y nodejs && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && \ apt-get install -y yarn
curl -fsSL https://deb.nodesource.com/setup_current.x | bash -
: NodeSource セットアップ スクリプトをダウンロードして実行し、Node.js をインストールします。
apt-get install -y nodejs
: Node.js をインストールします。
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
: パッケージを検証するために Yarn GPG キーを追加します。
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
: Yarn のリポジトリをソースのリストに追加します。
apt-get update && apt-get install -y yarn
: パッケージ リストを更新し、Yarn をインストールします。ENV NODE_OPTIONS=--openssl-legacy-provider
ENV NODE_OPTIONS=--openssl-legacy-provider
: Node.js の従来の OpenSSL サポートを有効にする環境変数を設定します。WORKDIR /rails
WORKDIR /rails
: 後続の命令の作業ディレクトリを/rails
に設定します。ARG RAILS_ENV ENV RAILS_ENV=$RAILS_ENV
ARG RAILS_ENV
: Rails 環境 ( development
、 test
、 production
など) を指定するためのRAILS_ENV
という名前のビルド引数を定義します。
ENV RAILS_ENV=$RAILS_ENV
: 環境変数RAILS_ENV
ビルド引数の値に設定します。COPY Gemfile Gemfile.lock ./ RUN bundle install
COPY Gemfile Gemfile.lock ./
: Gemfile
とGemfile.lock
を作業ディレクトリにコピーします。
RUN bundle install
: Gemfile
で指定された Ruby gem をインストールします。COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile
COPY package.json yarn.lock ./
: package.json
とyarn.lock
を作業ディレクトリにコピーします。
RUN yarn install --frozen-lockfile
: Yarn を使用してフロントエンドの依存関係をインストールし、 yarn.lock
内の正確なバージョンが使用されるようにします。COPY . .
COPY . .
: すべてのアプリケーション コードを作業ディレクトリにコピーします。RUN bundle exec bootsnap precompile --gemfile app/ lib/
RUN bundle exec bootsnap precompile --gemfile app/ lib/
: Rails アプリケーションの起動時間を短縮するために Bootsnap キャッシュを事前コンパイルします。Bootsnap は、高価な計算をキャッシュすることで Ruby と Rails の起動時間を短縮する gem です。RUN if [ "$RAILS_ENV" = "production" ]; then \ SECRET_KEY_BASE=1 bin/rails assets:precompile; \ fi
RUN if [ "$RAILS_ENV" = "production" ]; then
... : RAILS_ENV
がproduction
に設定されている場合にのみ、アセットの事前コンパイルを条件付きで実行します。この手順は、運用環境用のアセットを準備するために重要です。COPY bin/docker-entrypoint /rails/bin/ RUN chmod +x /rails/bin/docker-entrypoint
COPY bin/docker-entrypoint /rails/bin/
: カスタム エントリポイント スクリプトをコンテナにコピーします。
RUN chmod +x /rails/bin/docker-entrypoint
: エントリポイント スクリプトを実行可能にします。ENTRYPOINT ["/rails/bin/docker-entrypoint"] EXPOSE 5000 // you can use any port of your choice CMD ["./bin/rails", "server"]
ENTRYPOINT ["/rails/bin/docker-entrypoint"]
: コンテナの起動時に実行されるエントリポイント スクリプトを設定します。このスクリプトは通常、環境を設定し、データベースを準備し、アプリケーションを起動します。
EXPOSE 5000
: コンテナーがポート 5000 でリッスンすることを示します。これはドキュメント機能であり、ポートを公開するものではありません。
CMD ["./bin/rails", "server"]
: コンテナの起動時に実行されるデフォルトのコマンドを指定します。これは Rails サーバーを起動するためのものです。docker-compose.yml
ファイルは、マルチコンテナ Docker アプリケーションの定義と実行に使用されます。これにより、アプリケーションのサービス、ネットワーク、ボリュームを 1 つのファイルで構成できます。この例では、2 つのサービスを使用します。以下は、Rails アプリケーションのdocker-compose.yml
ファイルです。
db
) codedb: image: postgres:14.2-alpine container_name: demo-postgres-14.2 volumes: - postgres_data:/var/lib/postgresql/data command: "postgres -c 'max_connections=500'" environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} ports: - "5432:5432"
image: postgres:14.2-alpine
: このサービスに使用する Docker イメージを指定します。この場合、Alpine Linux ディストリビューションに基づく PostgreSQL 14.2 イメージです。Alpine イメージはサイズが小さいことで知られており、全体的なイメージ サイズを小さく抑えるのに役立ちます。
container_name: demo-postgres-14.2
: コンテナにdemo-postgres-14.2
名前を付けます。この名前は、コマンドとログでコンテナを参照するために使用されます。
volumes
: postgres_data:/var/lib/postgresql/data:
名前付きボリュームpostgres_data
をコンテナ内の/var/lib/postgresql/data
にマウントします。このディレクトリは PostgreSQL がデータを保存する場所であり、コンテナの再起動後もデータベース データが保持されることを保証します。
command: "postgres -c 'max_connections=500'"
: PostgreSQL イメージのデフォルト コマンドを上書きします。最大接続数を 500 に増やす構成オプションを使用して PostgreSQL を起動します。
environment
: POSTGRES_DB: ${POSTGRES_DB}
: 環境変数POSTGRES_DB
を使用して、作成するデフォルトのデータベースの名前を設定します。
POSTGRES_USER: ${POSTGRES_USER}
: POSTGRES_USER
環境変数を使用して、PostgreSQL データベースにアクセスするためのデフォルトのユーザー名を設定します。
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
: POSTGRES_PASSWORD
環境変数を使用して、デフォルト ユーザーのパスワードを設定します。
ports
:"5432:5432"
: ホストのポート 5432 をコンテナのポート 5432 にマップします。これにより、ポート 5432 経由でホスト マシン上の PostgreSQL にアクセスできるようになります。demo-web
) codedemo-web: build: context: . args: - RAILS_ENV=${RAILS_ENV} command: "./bin/rails server -b 0.0.0.0" environment: - RAILS_ENV=${RAILS_ENV} - POSTGRES_HOST=${POSTGRES_HOST} - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - RAILS_MASTER_KEY=${RAILS_MASTER_KEY} volumes: - .:/rails - app-storage:/rails/storage depends_on: - db ports: - "3000:3000"
build:
context: .
: Docker イメージのビルド コンテキストを指定します。この場合、 .
は現在のディレクトリを指します。つまり、Docker は現在のディレクトリの Dockerfile を使用してイメージをビルドします。args
: RAILS_ENV=${RAILS_ENV}
: RAILS_ENV
ビルド引数を Docker ビルドプロセスに渡し、Rails 環境 ( development
、 test
、 production
など) を指定できるようにします。
command: "./bin/rails server -b 0.0.0.0"
: Docker イメージのデフォルト コマンドを上書きします。Rails サーバーを起動し、それをすべてのネットワーク インターフェイス ( 0.0.0.0
) にバインドします。これは、コンテナーの外部からサービスにアクセスできるようにするために必要です。
environment:
RAILS_ENV=${RAILS_ENV}
: RAILS_ENV
環境変数を使用して、コンテナ内の Rails 環境を設定します。
POSTGRES_HOST=${POSTGRES_HOST}
: PostgreSQL ホストアドレスを設定します。
POSTGRES_DB=${POSTGRES_DB}
: データベース名を設定します。
POSTGRES_USER=${POSTGRES_USER}
: PostgreSQL ユーザーを設定します。
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
: PostgreSQL ユーザーのパスワードを設定します。
RAILS_MASTER_KEY=${RAILS_MASTER_KEY}
: 資格情報やその他のシークレットの暗号化に使用される Rails マスターキーを設定します。
volumes
:
.:/rails
: 現在のディレクトリ ( docker-compose.yml
ファイルがある場所) をコンテナ内の/rails
にマウントします。これにより、ホスト上のファイルを編集し、その変更をコンテナ内に反映させることができます。
app-storage:/rails/storage
: 名前付きボリュームapp-storage
をコンテナ内の/rails/storage
にマウントします。これは通常、ログ、アップロード、キャッシュされたファイルなどの Rails 固有のファイルを保存するために使用されます。
depends_on
:
db
: demo-web
サービスが起動する前に、 db
サービスの準備ができるまで待機するようにします。Docker Compose は、この設定に基づいてサービスの開始順序を処理します。 ports:
"3000:3000"
: ホストのポート 3000 をコンテナのポート 3000 にマップします。これにより、ポート 3000 経由でホスト マシン上の Rails アプリケーションにアクセスできるようになります。codevolumes: postgres_data: app-storage:
postgres_data
: PostgreSQL データを永続化するためにdb
サービスによって使用される名前付きボリュームpostgres_data
を定義します。app-storage
: アップロードやログなどのアプリケーション固有のデータを保持するために、 demo-web
サービスによって使用される名前付きボリュームapp-storage
を定義します。bin/docker-entrypoint
スクリプトは、Docker セットアップの重要な部分です。コンテナの起動時に実行され、通常は環境のセットアップ、データベースの準備、およびメイン アプリケーションの起動前に必要なその他の初期化タスクを処理します。次に、 bin/docker-entrypoint
スクリプトの例と各部分の詳細な説明を示します。
bashCopy code#!/bin/bash set -e
#!/bin/bash
: この行は、スクリプトを Bash シェルを使用して実行することを指定します。
set -e
: コマンドがゼロ以外の終了コードを返した場合にスクリプトを直ちに終了するように指示します。これにより、いずれかのステップが失敗した場合にスクリプトの実行が停止し、後続のステップが無効な状態で実行されるのを防ぐことができます。
条件付きデータベースの作成または移行
# If running the rails server then create or migrate existing database if [ "${*}" == "./bin/rails server" ]; then ./bin/rails db:create ./bin/rails db:prepare fi
"${*}"
) が./bin/rails server
であるかどうかを確認します。 *
は、スクリプトに渡されるすべての位置パラメータを保持する特別なパラメータです。
./bin/railsデータベース
: 条件が満たされた場合、このコマンドはデータベースの作成を試みます。これは、データベース設定ファイル ( config/database.yml
) で定義されているようにデータベースを設定するrails db:create
のと同じです。
./bin/railsデータベース
: このコマンドはrails db:prepare
実行し、データベースがセットアップされ、移行されていることを確認します。データベースが存在しない場合はデータベースを作成し、データベースがすでに作成されている場合は移行を実行します。これはrails db:create
とrails db:migrate
の組み合わせです。
bashCopy codeexec "${@}"
exec "${@}"
: 現在のシェル プロセスを、スクリプトに引数として渡されたコマンドに置き換えます。 @
記号には、スクリプトに渡されるすべての位置パラメータが含まれます。たとえば、スクリプトが./bin/rails server
で呼び出される場合、この行はコンテナのメイン プロセスとして./bin/rails server
を効果的に実行します。適切に作成されたDockerfile
、Ruby on Rails および React アプリケーション用の信頼性が高く一貫性のある環境を作成するために不可欠です。ベースイメージを定義し、環境変数を設定し、依存関係をインストールすることで、アプリケーションがさまざまな環境でスムーズに実行されるようになります。
Docker は開発プロセスを効率化するだけでなく、本番環境でのアプリケーションの信頼性も向上させます。最適化の領域もありますが、これは Rails アプリケーションを Docker 化する方法の一般的な概要にすぎません。
Dockerfile
、 docker-compose.yml
、 bin/docker-entrypoint
完全なスクリプトARG RUBY_VERSION=3.1.4 FROM ruby:$RUBY_VERSION # Install dependencies RUN apt-get update -qq && \ apt-get install -y build-essential libvips bash bash-completion libffi-dev tzdata postgresql curl && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man # Install Node.js and Yarn RUN curl -fsSL https://deb.nodesource.com/setup_current.x | bash - && \ apt-get install -y nodejs && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && \ apt-get install -y yarn # Set environment variable to enable legacy OpenSSL support ENV NODE_OPTIONS=--openssl-legacy-provider # Rails app lives here WORKDIR /rails # Set environment variable for the build ARG RAILS_ENV ENV RAILS_ENV=$RAILS_ENV # Install application gems COPY Gemfile Gemfile.lock ./ RUN bundle install # Install frontend dependencies COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile # Copy application code COPY . . # Precompile bootsnap code for faster boot times RUN bundle exec bootsnap precompile --gemfile app/ lib/ # Precompiling assets for production without requiring secret RAILS_MASTER_KEY RUN if [ "$RAILS_ENV" = "production" ]; then \ SECRET_KEY_BASE=1 bin/rails assets:precompile; \ fi # Entrypoint prepares the database. COPY bin/docker-entrypoint /rails/bin/ RUN chmod +x /rails/bin/docker-entrypoint # Use an absolute path for the entry point script ENTRYPOINT ["/rails/bin/docker-entrypoint"] # Start the server by default, this can be overwritten at runtime EXPOSE 5000 CMD ["./bin/rails", "server"]
services: db: image: postgres:14.2-alpine container_name: demo-postgres-14.2 volumes: - postgres_data:/var/lib/postgresql/data command: "postgres -c 'max_connections=500'" environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} ports: - "5432:5432" demo-web: build: context: . args: - RAILS_ENV=${RAILS_ENV} command: "./bin/rails server -b 0.0.0.0" environment: - RAILS_ENV=${RAILS_ENV} - POSTGRES_HOST=${POSTGRES_HOST} - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - RAILS_MASTER_KEY=${RAILS_MASTER_KEY} volumes: - .:/rails - app-storage:/rails/storage depends_on: - db ports: - "3000:3000" volumes: postgres_data: app-storage:
#!/bin/bash set -e # If running the rails server then create or migrate existing database if [ "${*}" == "./bin/rails server" ]; then ./bin/rails db:create ./bin/rails db:prepare fi exec "${@}"