paint-brush
React フロントエンド アプリを使用した Ruby と Rails の「Docker 化」の簡易ガイド@forison
319 測定値
319 測定値

React フロントエンド アプリを使用した Ruby と Rails の「Docker 化」の簡易ガイド

Addo Boakye Forison13m2024/08/04
Read on Terminal Reader

長すぎる; 読むには

Docker 化には、イメージとコンテナという 2 つの重要な概念が関係します。イメージはコンテナの設計図として機能し、コンテナを作成するために必要なすべての情報が含まれています。コンテナはイメージのランタイム インスタンスであり、イメージ自体、実行環境、およびランタイム命令で構成されます。この記事では、Rails および React アプリケーションを Docker 化する実践的なガイドを詳細に紹介します。
featured image - React フロントエンド アプリを使用した Ruby と Rails の「Docker 化」の簡易ガイド
Addo Boakye Forison HackerNoon profile picture
0-item
1-item

React フロントエンド アプリケーションを使用して Ruby on Rails を Docker 化すると、開発ワークフローとデプロイメント プロセスが大幅に改善されます。アプリの標準化された環境を作成することで、開発、テスト、運用のさまざまな段階、さらには異なるシステム間でも一貫した動作が保証されます。実際、システムの違いに関連する問題を最小限に抑えるように設計されています。このガイドでは、Rails および React アプリを Docker コンテナーでスムーズに実行するための重要な手順について説明します。

Dockerが救世主

アプリケーションを Docker 化する理由

  • 環境間の一貫性:
    • Docker は、開発者のマシン、テスト環境、実稼働サーバーなど、どこにデプロイされてもアプリケーションが同じように実行されることを保証します。この一貫性は、すべての依存関係と構成をコンテナ化することで実現されます。


  • 依存関係管理:
    • Docker コンテナには、アプリケーションを実行するために必要なすべての依存関係が含まれています。つまり、システム ライブラリのバリエーションや、異なるシステムでの依存関係の欠落がアプリケーションの機能に影響を与えることはありません。


  • 分離
    • Docker コンテナは、互いに、またホスト システムから分離して実行されます。この分離により、同じシステム上の異なるアプリケーションとそれらの依存関係間の競合が防止されます。


  • 携帯性:
    • Docker コンテナは、ローカル マシン、クラウド サービス、専用サーバーなど、Docker をサポートする任意のシステム上で簡単に移動して実行できます。これにより、アプリケーションの移植性が高くなり、展開の柔軟性が高まります。


注意: Docker構文の知識が必要です


Docker 化には、イメージとコンテナという 2 つの重要な概念が関係します。イメージはコンテナの設計図として機能し、依存関係やデプロイメント構成など、コンテナを作成するために必要なすべての情報が含まれています。コンテナはイメージのランタイム インスタンスであり、イメージ自体、実行環境、およびランタイム命令で構成されます。一般的に、Docker はソフトウェアの出荷の標準を確立します。


Docker を簡単な例えで説明すると、コンテナを庭にある輸送コンテナ、イメージをコンテナ内に置かれたアイテム、輸送船をコンテナが実行されるシステムと考えてください。


アプリケーションをセットアップしてビルドするときは常に、特定の環境設定が必要です。たとえば、システムに Ruby 環境がインストールされていないと、Rails アプリケーションを実行することはできません。同様に、 Node.jsがないと React アプリケーションを実行できず、 npmYarnなどの Node パッケージ マネージャーがないと React パッケージをインストールできません。


コンテナはユーザーのシステムから独立して実行されるため、システム上に直接構築した場合と同じように、これらすべてのパッケージをコンテナ内で利用できるようにします。これにより、コンテナは仮想マシンのように独自のシステムとして機能します。Docker と仮想マシンには違いがありますが、この例はさらに説明するためのものです。


それでは、Rails アプリケーションを Docker 化してみましょう。これを行うには、Rails アプリケーションにDockerfiledocker-compose.ymlbin/docker-entrypoint 3 つのファイルが必要になります。これらの各ファイルを詳しく見ていきましょう。


注意: Docker構文の知識が必要です

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 がインストールされている必要があります。

2. 依存関係をインストールする

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 : 画像処理用のライブラリ。

    • bashbash-completion : Bash シェルとその自動補完。

    • libffi-dev : 外部関数インターフェースライブラリ。

    • tzdata : タイムゾーンデータ。

    • postgresql : PostgreSQL データベース クライアント。

    • curl : URL からデータを転送するためのツール。


  • apt-get clean : 取得したパッケージ ファイルのローカル リポジトリをクリーンアップします。


  • rm -rf /var/lib/apt/lists/ /usr/share/doc /usr/share/man : イメージのサイズを縮小するためにパッケージ リストとドキュメントを削除します。

3. Node.jsと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
  • 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 をインストールします。

4. 環境変数

ENV NODE_OPTIONS=--openssl-legacy-provider
  • ENV NODE_OPTIONS=--openssl-legacy-provider : Node.js の従来の OpenSSL サポートを有効にする環境変数を設定します。

5. 作業ディレクトリを設定する

WORKDIR /rails
  • WORKDIR /rails : 後続の命令の作業ディレクトリを/railsに設定します。

6. ビルド引数と環境変数

ARG RAILS_ENV ENV RAILS_ENV=$RAILS_ENV
  • ARG RAILS_ENV : Rails 環境 ( developmenttestproductionなど) を指定するためのRAILS_ENVという名前のビルド引数を定義します。


  • ENV RAILS_ENV=$RAILS_ENV : 環境変数RAILS_ENVビルド引数の値に設定します。

7. アプリケーションGemをインストールする

COPY Gemfile Gemfile.lock ./ RUN bundle install
  • COPY Gemfile Gemfile.lock ./ : GemfileGemfile.lockを作業ディレクトリにコピーします。


  • RUN bundle install : Gemfileで指定された Ruby gem をインストールします。

8. フロントエンドの依存関係をインストールする

COPY package.json yarn.lock ./ RUN yarn install --frozen-lockfile
  • COPY package.json yarn.lock ./ : package.jsonyarn.lockを作業ディレクトリにコピーします。


  • RUN yarn install --frozen-lockfile : Yarn を使用してフロントエンドの依存関係をインストールし、 yarn.lock内の正確なバージョンが使用されるようにします。

9. アプリケーションコードをコピーする

COPY . .
  • COPY . . : すべてのアプリケーション コードを作業ディレクトリにコピーします。

10. Bootsnap コードを事前コンパイルする

RUN bundle exec bootsnap precompile --gemfile app/ lib/
  • RUN bundle exec bootsnap precompile --gemfile app/ lib/ : Rails アプリケーションの起動時間を短縮するために Bootsnap キャッシュを事前コンパイルします。Bootsnap は、高価な計算をキャッシュすることで Ruby と Rails の起動時間を短縮する gem です。

11. 制作用にアセットを事前コンパイルする

RUN if [ "$RAILS_ENV" = "production" ]; then \ SECRET_KEY_BASE=1 bin/rails assets:precompile; \ fi
  • RUN if [ "$RAILS_ENV" = "production" ]; then ... : RAILS_ENVproductionに設定されている場合にのみ、アセットの事前コンパイルを条件付きで実行します。この手順は、運用環境用のアセットを準備するために重要です。

12. エントリポイントスクリプト

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 : エントリポイント スクリプトを実行可能にします。

13. エントリポイントとコマンドを定義する

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ファイルです。

1.データベースサービス ( 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 にアクセスできるようになります。

2. Webアプリケーションサービス( 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 環境 ( developmenttestproductionなど) を指定できるようにします。


  • 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-エントリポイント

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


  • if [ "${*}" == "./bin/rails server" ]; then ... fi : この条件文は、スクリプトに渡されたコマンド ( "${*}" ) が./bin/rails serverであるかどうかを確認します。 *は、スクリプトに渡されるすべての位置パラメータを保持する特別なパラメータです。


  • ./bin/railsデータベース

    : 条件が満たされた場合、このコマンドはデータベースの作成を試みます。これは、データベース設定ファイル ( config/database.yml ) で定義されているようにデータベースを設定するrails db:createのと同じです。


  • ./bin/railsデータベース

    : このコマンドはrails db:prepare実行し、データベースがセットアップされ、移行されていることを確認します。データベースが存在しない場合はデータベースを作成し、データベースがすでに作成されている場合は移行を実行します。これはrails db:createrails db:migrateの組み合わせです。

    メインプロセスの実行

    bashCopy codeexec "${@}"
    • exec "${@}" : 現在のシェル プロセスを、スクリプトに引数として渡されたコマンドに置き換えます。 @記号には、スクリプトに渡されるすべての位置パラメータが含まれます。たとえば、スクリプトが./bin/rails serverで呼び出される場合、この行はコンテナのメイン プロセスとして./bin/rails serverを効果的に実行します。

結論

適切に作成されたDockerfile 、Ruby on Rails および React アプリケーション用の信頼性が高く一貫性のある環境を作成するために不可欠です。ベースイメージを定義し、環境変数を設定し、依存関係をインストールすることで、アプリケーションがさまざまな環境でスムーズに実行されるようになります。


Docker は開発プロセスを効率化するだけでなく、本番環境でのアプリケーションの信頼性も向上させます。最適化の領域もありますが、これは Rails アプリケーションを Docker 化する方法の一般的な概要にすぎません。

結果として得られるDockerfiledocker-compose.ymlbin/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 "${@}"