序章

アプリケーションを積極的に開発している場合は、 Docker を使用すると、ワークフローとアプリケーションを本番環境にデプロイするプロセスを簡素化できます。 開発中のコンテナを使用すると、次の利点があります。

  • 環境は一貫しています。つまり、システムの競合を心配することなく、プロジェクトに必要な言語と依存関係を選択できます。
  • 環境が分離されているため、問題のトラブルシューティングや新しいチームメンバーの参加が容易になります。
  • 環境は移植可能であり、コードをパッケージ化して他の人と共有することができます。

このチュートリアルでは、Dockerを使用して Ruby onRailsアプリケーションの開発環境をセットアップする方法を説明します。 Docker Compose を使用して、アプリケーション自体、 PostgreSQL データベース、 Redis 、およびSidekiqサービス用に複数のコンテナーを作成します。 セットアップは次のことを行います。

  • ホスト上のアプリケーションコードをコンテナ内のコードと同期して、開発中の変更を容易にします。
  • コンテナの再起動間でアプリケーションデータを保持します。
  • 期待どおりにジョブを処理するようにSidekiqワーカーを構成します。

このチュートリアルの最後に、Dockerコンテナで実行されている動作するサメ情報アプリケーションがあります。

前提条件

このチュートリアルに従うには、次のものが必要です。

  • Ubuntu 18.04を実行しているローカル開発マシンまたはサーバーと、root以外のユーザー sudo 特権とアクティブなファイアウォール。 これらの設定方法のガイダンスについては、この初期サーバー設定ガイドを参照してください。
  • Ubuntu18.04にDockerをインストールして使用する方法の手順1と2に従ってローカルマシンまたはサーバーにDockerをインストールします。
  • Ubuntu 18.04にDockerComposeをインストールする方法のステップ1に従って、ローカルマシンまたはサーバーにDockerComposeをインストールします。

ステップ1—プロジェクトのクローンを作成して依存関係を追加する

最初のステップは、 DigitalOceanCommunityGitHubアカウントからrails-sidekiqリポジトリのクローンを作成することです。 このリポジトリには、既存のRails5プロジェクトにSidekiqを追加する方法を説明するRubyonRailsアプリケーションにSidekiqとRedisを追加する方法で説明されているセットアップのコードが含まれています。

リポジトリをと呼ばれるディレクトリに複製します rails-docker:

  1. git clone https://github.com/do-community/rails-sidekiq.git rails-docker

に移動します rails-docker ディレクトリ:

  1. cd rails-docker

このチュートリアルでは、PostgreSQLをデータベースとして使用します。 SQLite 3の代わりにPostgreSQLを使用するには、Gemfileにリストされているプロジェクトの依存関係に pggemを追加する必要があります。 を使用して編集するためにそのファイルを開きます nano またはお気に入りの編集者:

  1. nano Gemfile

メインプロジェクトの依存関係(開発の依存関係の上)の任意の場所にgemを追加します。

〜/ rails-docker / Gemfile
. . . 
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.1.0', require: false
gem 'sidekiq', '~>6.0.0'
gem 'pg', '~>1.1.3'

group :development, :test do
. . .

sqlite gem はもう使用しないため、コメントアウトすることもできます。

〜/ rails-docker / Gemfile
. . . 
# Use sqlite3 as the database for Active Record
# gem 'sqlite3'
. . .

最後に、 spring-watcher-listengemをコメントアウトします。 development:

〜/ rails-docker / Gemfile
. . . 
gem 'spring'
# gem 'spring-watcher-listen', '~> 2.0.0'
. . .

このgemを無効にしないと、Railsコンソールにアクセスするときに永続的なエラーメッセージが表示されます。 これらのエラーメッセージは、このgemがファイルシステムの変更をポーリングするのではなく、Railsがlistenを使用して開発の変更を監視しているという事実に由来しています。 この宝石はプロジェクトのルートを監視しているため、 node_modules ディレクトリの場合、監視されているディレクトリに関するエラーメッセージがスローされ、コンソールが乱雑になります。 ただし、CPUリソースの節約が心配な場合は、このgemを無効にしてもうまくいかない可能性があります。 この場合、RailsアプリケーションをRails6にアップグレードすることをお勧めします。

編集が終了したら、ファイルを保存して閉じます。

プロジェクトリポジトリを配置すると、 pg Gemfileに追加されたgem、および spring-watcher-listen gemがコメントアウトしました。これで、PostgreSQLで動作するようにアプリケーションを構成する準備が整いました。

ステップ2—PostgreSQLおよびRedisで動作するようにアプリケーションを構成する

開発中のPostgreSQLとRedisを使用するには、次のことを行います。

  • PostgreSQLをデフォルトのアダプターとして使用するようにアプリケーションを構成します。
  • 追加します .env データベースのユーザー名とパスワード、およびRedisホストを使用してプロジェクトにファイルします。
  • 作成する init.sql 作成するスクリプト sammy データベースのユーザー。
  • Sidekiq用のinitializerを追加して、コンテナ化されたもので動作できるようにします redis サービス。
  • 追加します .env プロジェクトのファイルおよびその他の関連ファイル gitignoredockerignore ファイル。
  • データベースシードを作成して、アプリケーションの起動時に使用できるレコードがアプリケーションに含まれるようにします。

まず、次の場所にあるデータベース構成ファイルを開きます。 config/database.yml:

  1. nano config/database.yml

現在、ファイルには次のものが含まれています default 他の設定がない場合に適用される設定:

〜/ rails-docker / config / database.yml
default: &default
  adapter: sqlite3
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

を使用するという事実を反映するために、これらを変更する必要があります postgresql アプリケーションデータを永続化するためにDockerComposeを使用してPostgreSQLサービスを作成するためです。

SQLiteをアダプターとして設定するコードを削除し、次の設定に置き換えます。これにより、アダプターと接続に必要なその他の変数が適切に設定されます。

〜/ rails-docker / config / database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  database: <%= ENV['DATABASE_NAME'] %>
  username: <%= ENV['DATABASE_USER'] %>
  password: <%= ENV['DATABASE_PASSWORD'] %>
  port: <%= ENV['DATABASE_PORT'] || '5432' %>
  host: <%= ENV['DATABASE_HOST'] %>
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000
. . .

次に、の設定を変更します development これは、このセットアップで使用している環境であるためです。

セクションが次のようになるように、既存のSQLiteデータベース構成を削除します。

〜/ rails-docker / config / database.yml
. . . 
development:
  <<: *default
. . .

最後に、 database の設定 productiontest 環境も:

〜/ rails-docker / config / database.yml
. . . 
test:
  <<: *default
  
production:
  <<: *default
. . . 

デフォルトのデータベース設定に対するこれらの変更により、で定義された環境変数を使用してデータベース情報を動的に設定できるようになります。 .env バージョン管理にコミットされないファイル。

編集が終了したら、ファイルを保存して閉じます。

Railsプロジェクトを最初から作成する場合は、アダプターを次のように設定できることに注意してください。 rails new Ubuntu18.04上のRubyonRailsアプリケーションでPostgreSQLを使用する方法のステップ3で説明されているコマンド。 これにより、アダプタがに設定されます config/database.yml 自動的に追加します pg プロジェクトへの宝石。

環境変数を参照したので、好みの設定でそれらのファイルを作成できます。 この方法で構成設定を抽出することは、アプリケーション開発への 12ファクターアプローチの一部であり、分散環境でのアプリケーションの復元力のベストプラクティスを定義します。 現在、将来的に本番環境とテスト環境をセットアップする場合、データベース設定の構成には追加の作成が含まれます .env ファイルとDockerComposeファイル内の適切なファイルの参照。

開く .env ファイル:

  1. nano .env

次の値をファイルに追加します。

〜/ rails-docker / .env
DATABASE_NAME=rails_development
DATABASE_USER=sammy
DATABASE_PASSWORD=shark
DATABASE_HOST=database
REDIS_HOST=redis

データベース名、ユーザー、パスワードの設定に加えて、 DATABASE_HOST. 値、 database、 を参照 database DockerComposeを使用して作成するPostgreSQLサービス。 また、 REDIS_HOST 私たちを指定するには redis サービス。

編集が終了したら、ファイルを保存して閉じます。

を作成するには sammy データベースユーザー、私たちは書くことができます init.sql 起動時にデータベースコンテナにマウントできるスクリプト。

スクリプトファイルを開きます。

  1. nano init.sql

次のコードを追加して、 sammy 管理者権限を持つユーザー:

〜/ rails-docker / init.sql
CREATE USER sammy;
ALTER USER sammy WITH SUPERUSER;

このスクリプトは、データベース上に適切なユーザーを作成し、このユーザーに管理者権限を付与します。

スクリプトに適切な権限を設定します。

  1. chmod +x init.sql

次に、コンテナ化されたコンテナで動作するようにSidekiqを構成します redis サービス。 イニシャライザを追加できます config/initializers フレームワークとプラグインがロードされるとRailsが構成設定を探すディレクトリ。Redisホストの値を設定します。

開く sidekiq.rb これらの設定を指定するファイル:

  1. nano config/initializers/sidekiq.rb

次のコードをファイルに追加して、 REDIS_HOSTREDIS_PORT:

〜/ rails-docker / config / initializers / sidekiq.rb
Sidekiq.configure_server do |config|
  config.redis = {
    host: ENV['REDIS_HOST'],
    port: ENV['REDIS_PORT'] || '6379'
  }
end

Sidekiq.configure_client do |config|
  config.redis = {
    host: ENV['REDIS_HOST'],
    port: ENV['REDIS_PORT'] || '6379'
  }
end

データベース構成設定と同様に、これらの設定により、ホストとポートのパラメーターを動的に設定できるため、アプリケーションコード自体を変更することなく、実行時に適切な値に置き換えることができます。 に加えて REDIS_HOST、デフォルト値が設定されています REDIS_PORT 他に設定されていない場合。

編集が終了したら、ファイルを保存して閉じます。

次に、アプリケーションの機密データがバージョン管理にコピーされないようにするために、次のように追加できます。 .env 私たちのプロジェクトに .gitignore file。プロジェクトで無視するファイルをGitに指示します。 編集用にファイルを開きます。

  1. nano .gitignore

ファイルの下部に、次のエントリを追加します .env:

〜/ rails-docker / .gitignore
yarn-debug.log*
.yarn-integrity
.env

編集が終了したら、ファイルを保存して閉じます。

次に、を作成します .dockerignore コンテナにコピーしないものを設定するファイル。 編集用にファイルを開きます。

  1. .dockerignore

次のコードをファイルに追加します。これにより、Dockerは、コンテナーにコピーする必要のないものの一部を無視するようになります。

〜/ rails-docker / .dockerignore
.DS_Store
.bin
.git
.gitignore
.bundleignore
.bundle
.byebug_history
.rspec
tmp
log
test
config/deploy
public/packs
public/packs-test
node_modules
yarn-error.log
coverage/

追加 .env このファイルの最後にも:

〜/ rails-docker / .dockerignore
. . .
yarn-error.log
coverage/
.env

編集が終了したら、ファイルを保存して閉じます。

最後のステップとして、アプリケーションを起動したときにいくつかのレコードが含まれるように、いくつかのシードデータを作成します。

シードデータのファイルを開きます db ディレクトリ:

  1. nano db/seeds.rb

次のコードをファイルに追加して、4つのデモサメと1つのサンプル投稿を作成します。

〜/ rails-docker / db / seeds.rb
# Adding demo sharks
sharks = Shark.create([{ name: 'Great White', facts: 'Scary' }, { name: 'Megalodon', facts: 'Ancient' }, { name: 'Hammerhead', facts: 'Hammer-like' }, { name: 'Speartooth', facts: 'Endangered' }])
Post.create(body: 'These sharks are misunderstood', shark: sharks.first)

このシードデータは、最初のサメに関連付けられた4つのサメと1つの投稿を作成します。

編集が終了したら、ファイルを保存して閉じます。

アプリケーションがPostgreSQLで動作するように構成され、環境変数が作成されたら、アプリケーションDockerfileを作成する準備が整います。

ステップ3—Dockerfileおよびエントリポイントスクリプトの記述

Dockerfileは、作成時にアプリケーションコンテナに含まれるものを指定します。 Dockerfileを使用すると、コンテナー環境を定義し、依存関係またはランタイムバージョンとの不一致を回避できます。

最適化されたコンテナの構築に関するこれらのガイドラインに従い、アルパインベースを使用し、画像レイヤーを一般的に最小化することで、画像を可能な限り効率的にします。

現在のディレクトリでDockerfileを開きます。

  1. nano Dockerfile

Dockerイメージは、相互に構築される一連のレイヤードイメージを使用して作成されます。 最初のステップは、アプリケーションのベースイメージを追加することです。これにより、アプリケーションビルドの開始点が形成されます。

次のコードをファイルに追加して、 Ruby alpineimageをベースとして追加します。

〜/ rails-docker / Dockerfile
FROM ruby:2.5.1-alpine

The alpine imageはAlpineLinuxプロジェクトから派生しており、画像サイズを小さく抑えるのに役立ちます。 かどうかの詳細については alpine 画像はプロジェクトに適した選択です。DockerHubRuby画像ページ画像バリアントセクションの詳細な説明を参照してください。

使用する際に考慮すべきいくつかの要因 alpine 開発中:

  • 画像サイズを小さくすると、特にボリュームを最小限に抑える場合は、ページとリソースの読み込み時間が短縮されます。 これにより、開発におけるユーザーエクスペリエンスを迅速に保ち、コンテナ化されていない環境でローカルで作業している場合のエクスペリエンスに近づけることができます。
  • 開発イメージと本番イメージの間に同等性があると、展開の成功が容易になります。 チームはスピードのメリットのために本番環境でアルパインイメージを使用することを選択することが多いため、アルパインベースで開発すると、本番環境に移行する際の問題を相殺するのに役立ちます。

次に、環境変数を設定して、Bundlerバージョンを指定します。

〜/ rails-docker / Dockerfile
. . .
ENV BUNDLER_VERSION=2.0.2

これは、デフォルト間のバージョンの競合を回避するために実行する手順の1つです。 bundler 私たちの環境で利用可能なバージョンと、Bundler2.0.2を必要とするアプリケーションコード。

次に、アプリケーションでの作業に必要なパッケージをDockerfileに追加します。

〜/ rails-docker / Dockerfile
. . . 
RUN apk add --update --no-cache \
      binutils-gold \
      build-base \
      curl \
      file \
      g++ \
      gcc \
      git \
      less \
      libstdc++ \
      libffi-dev \
      libc-dev \ 
      linux-headers \
      libxml2-dev \
      libxslt-dev \
      libgcrypt-dev \
      make \
      netcat-openbsd \
      nodejs \
      openssl \
      pkgconfig \
      postgresql-dev \
      python \
      tzdata \
      yarn 

これらのパッケージには次のものが含まれます nodejsyarn、とりわけ。 アプリケーションはwebpackでアセットを提供するため、アプリケーションが期待どおりに機能するには、Node.jsYarnを含める必要があります。

覚えておいてください alpine イメージは非常に最小限です。ここにリストされているパッケージは、独自のアプリケーションをコンテナー化するときに開発で必要になる可能性のあるものを網羅しているわけではありません。

次に、適切なをインストールします bundler バージョン:

〜/ rails-docker / Dockerfile
. . . 
RUN gem install bundler -v 2.0.2

この手順により、コンテナ化された環境とこのプロジェクトの仕様との同等性が保証されます。 Gemfile.lock ファイル。

次に、コンテナにアプリケーションの作業ディレクトリを設定します。

〜/ rails-docker / Dockerfile
. . .
WORKDIR /app

あなたの GemfileGemfile.lock:

〜/ rails-docker / Dockerfile
. . .
COPY Gemfile Gemfile.lock ./

これらのファイルを独立した手順としてコピーし、その後に bundle installは、アプリケーションコードに変更を加えるたびにプロジェクトgemを再構築する必要がないことを意味します。 これは、Composeファイルに含めるgemボリュームと連携して機能します。このボリュームは、サービスが再作成されてもプロジェクトgemが同じである場合に、アプリケーションコンテナーにgemをマウントします。

次に、の構成オプションを設定します nokogiri ジェムビルド:

〜/ rails-docker / Dockerfile
. . . 
RUN bundle config build.nokogiri --use-system-libraries
. . .

このステップはビルドします nokigiri libxml2およびlibxsltライブラリバージョンを使用してアプリケーションコンテナに追加しました RUN apk add… 上記のステップ。

次に、プロジェクトgemをインストールします。

〜/ rails-docker / Dockerfile
. . . 
RUN bundle check || bundle install

この手順では、gemをインストールする前に、gemがまだインストールされていないことを確認します。

次に、JavaScriptパッケージと依存関係を使用してgemで使用したのと同じ手順を繰り返します。 最初にパッケージメタデータをコピーし、次に依存関係をインストールし、最後にアプリケーションコードをコンテナイメージにコピーします。

DockerfileのJavascriptセクションを開始するには、次のようにコピーします。 package.jsonyarn.lock ホスト上の現在のプロジェクトディレクトリからコンテナへ:

〜/ rails-docker / Dockerfile
. . . 
COPY package.json yarn.lock ./

次に、必要なパッケージをでインストールします yarn install:

〜/ rails-docker / Dockerfile
. . . 
RUN yarn install --check-files

この指示には、 --check-files フラグ yarn コマンド、以前にインストールされたファイルが削除されていないことを確認する機能。 私たちの宝石の場合のように、私たちはパッケージの永続性を管理します node_modules Composeファイルを書き込むときのボリュームのあるディレクトリ。

最後に、残りのアプリケーションコードをコピーして、エントリポイントスクリプトを使用してアプリケーションを起動します。

〜/ rails-docker / Dockerfile
. . . 
COPY . ./ 

ENTRYPOINT ["./entrypoints/docker-entrypoint.sh"]

エントリポイントスクリプトを使用すると、コンテナを実行可能ファイルとして実行できます。

最終的なDockerfileは次のようになります。

〜/ rails-docker / Dockerfile
FROM ruby:2.5.1-alpine

ENV BUNDLER_VERSION=2.0.2

RUN apk add --update --no-cache \
      binutils-gold \
      build-base \
      curl \
      file \
      g++ \
      gcc \
      git \
      less \
      libstdc++ \
      libffi-dev \
      libc-dev \ 
      linux-headers \
      libxml2-dev \
      libxslt-dev \
      libgcrypt-dev \
      make \
      netcat-openbsd \
      nodejs \
      openssl \
      pkgconfig \
      postgresql-dev \
      python \
      tzdata \
      yarn 

RUN gem install bundler -v 2.0.2

WORKDIR /app

COPY Gemfile Gemfile.lock ./

RUN bundle config build.nokogiri --use-system-libraries

RUN bundle check || bundle install 

COPY package.json yarn.lock ./

RUN yarn install --check-files

COPY . ./ 

ENTRYPOINT ["./entrypoints/docker-entrypoint.sh"]

編集が終了したら、ファイルを保存して閉じます。

次に、というディレクトリを作成します entrypoints エントリポイントスクリプトの場合:

  1. mkdir entrypoints

このディレクトリには、メインのエントリポイントスクリプトとSidekiqサービスのスクリプトが含まれます。

アプリケーションエントリポイントスクリプトのファイルを開きます。

  1. nano entrypoints/docker-entrypoint.sh

次のコードをファイルに追加します。

rails-docker / entrypoints / docker-entrypoint.sh
#!/bin/sh

set -e

if [ -f tmp/pids/server.pid ]; then
  rm tmp/pids/server.pid
fi

bundle exec rails s -b 0.0.0.0

最初の重要な行は set -e、これは /bin/sh スクリプトの後半で問題が発生した場合にスクリプトを実行して高速で失敗するシェル。 次に、スクリプトはそれをチェックします tmp/pids/server.pid アプリケーションの起動時にサーバーの競合が発生しないようにするために、は存在しません。 最後に、スクリプトはRailsサーバーを起動します。 bundle exec rails s 指図。 を使用します -b このコマンドを使用して、サーバーをデフォルトではなくすべてのIPアドレスにバインドするオプション。 localhost. この呼び出しにより、Railsサーバーは着信要求をデフォルトではなくコンテナIPにルーティングします。 localhost.

編集が終了したら、ファイルを保存して閉じます。

スクリプトを実行可能にします。

  1. chmod +x entrypoints/docker-entrypoint.sh

次に、スクリプトを作成して開始します sidekiq Sidekiqジョブを処理するサービス。 このアプリケーションがSidekiqを使用する方法の詳細については、SidekiqとRedisをRubyonRailsアプリケーションに追加する方法を参照してください。

Sidekiqエントリポイントスクリプトのファイルを開きます。

  1. nano entrypoints/sidekiq-entrypoint.sh

Sidekiqを起動するには、ファイルに次のコードを追加します。

〜/ rails-docker / entrypoints / sidekiq-entrypoint.sh
#!/bin/sh

set -e

if [ -f tmp/pids/server.pid ]; then
  rm tmp/pids/server.pid
fi
 
bundle exec sidekiq

このスクリプトは、アプリケーションバンドルのコンテキストでSidekiqを起動します。

編集が終了したら、ファイルを保存して閉じます。 実行可能にする:

  1. chmod +x entrypoints/sidekiq-entrypoint.sh

エントリポイントスクリプトとDockerfileを配置すると、Composeファイルでサービスを定義する準備が整います。

ステップ4—DockerComposeを使用したサービスの定義

Docker Composeを使用すると、セットアップに必要な複数のコンテナーを実行できるようになります。 メインでComposeservicesを定義します docker-compose.yml ファイル。 Composeのサービスは、実行中のコンテナーであり、サービス定義です。これをユーザーに含めます。 docker-compose.yml file —各コンテナイメージの実行方法に関する情報が含まれています。 作成ツールを使用すると、複数のサービスを定義して、マルチコンテナーアプリケーションを構築できます。

アプリケーションのセットアップには、次のサービスが含まれます。

  • アプリケーション自体
  • PostgreSQLデータベース
  • Redis
  • Sidekiq

また、セットアップの一部としてバインドマウントを含めるため、開発中に行ったコードの変更は、このコードにアクセスする必要のあるコンテナーとすぐに同期されます。

私たちはではなくを定義していることに注意してください test テストはこのチュートリアルとシリーズの範囲外であるため、サービスですが、ここで使用している前例に従うことでテストできます。 sidekiq サービス。

を開きます docker-compose.yml ファイル:

  1. nano docker-compose.yml

まず、アプリケーションサービス定義を追加します。

〜/ rails-docker / docker-compose.yml
version: '3.4'

services:
  app: 
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
      - database
      - redis
    ports: 
      - "3000:3000"
    volumes:
      - .:/app
      - gem_cache:/usr/local/bundle/gems
      - node_modules:/app/node_modules
    env_file: .env
    environment:
      RAILS_ENV: development

The app サービス定義には、次のオプションが含まれます。

  • build:これは、以下を含む構成オプションを定義します。 contextdockerfile、これは、Composeがアプリケーションイメージをビルドするときに適用されます。 Docker Hub などのレジストリの既存のイメージを使用する場合は、代わりに image命令を使用して、ユーザー名、リポジトリ、イメージタグに関する情報を使用できます。
  • context:これは、イメージビルドのビルドコンテキスト(この場合は現在のプロジェクトディレクトリ)を定義します。
  • dockerfile:これは Dockerfile Composeがアプリケーションイメージのビルドに使用するファイルとして、現在のプロジェクトディレクトリにあります。
  • depends_on:これは databaseredis 最初にコンテナを稼働させてから app.
  • ports:これはポートをマップします 3000 ホストからポートへ 3000 コンテナに。
  • volumes:ここには2種類のマウントが含まれています:
    • 1つ目は、 bind mount で、ホスト上のアプリケーションコードをにマウントします。 /app コンテナのディレクトリ。 これにより、ホストコードに加えた変更がすぐにコンテナに入力されるため、迅速な開発が容易になります。
    • 2つ目は、 volume という名前で、 gem_cache. いつ bundle install 命令はコンテナで実行され、プロジェクトgemをインストールします。 このボリュームを追加すると、コンテナを再作成すると、gemが新しいコンテナにマウントされます。 このマウントは、プロジェクトに変更がないことを前提としているため、開発中にプロジェクトgemに do 変更を加える場合は、アプリケーションサービスを再作成する前に、このボリュームを削除することを忘れないでください。
    • 3番目のボリュームは、 node_modules ディレクトリ。 持っているのではなく node_modules ホストにマウントされると、開発中にパッケージの不一致や権限の競合が発生する可能性があります。このボリュームは、このディレクトリ内のパッケージが永続化され、プロジェクトの現在の状態を反映することを保証します。 この場合も、プロジェクトのノード依存関係を変更する場合は、このボリュームを削除して再作成する必要があります。
  • env_file:これは、Composeに、というファイルから環境変数を追加することを通知します。 .env ビルドコンテキストにあります。
  • environment:このオプションを使用すると、機密性の低い環境変数を設定して、Rails環境に関する情報をコンテナに渡すことができます。

次に、以下 app サービス定義、次のコードを追加して、 database サービス:

〜/ rails-docker / docker-compose.yml
. . .
  database:
    image: postgres:12.1
    volumes:
      - db_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql

とは異なり app サービス、 database サービスは postgres DockerHubから直接画像。 バージョンをに設定するのではなく、ここに固定していることに注意してください latest または指定しない(デフォルトは latest). このようにして、このセットアップがここで指定されたバージョンで機能することを確認し、イメージへのコード変更を壊すことによる予期しない驚きを回避できます。

また、 db_data ここにボリュームがあります。これにより、コンテナの起動間でアプリケーションデータが保持されます。 さらに、私たちは init.sql 適切なディレクトリへの起動スクリプト、 docker-entrypoint-initdb.d/ コンテナ上で、 sammy データベースユーザー。 画像のエントリポイントがデフォルトを作成した後 postgres ユーザーとデータベース、それはで見つかったすべてのスクリプトを実行します docker-entrypoint-initdb.d/ ディレクトリ。必要な初期化タスクに使用できます。 詳細については、PostgreSQLイメージドキュメント初期化スクリプトセクションを参照してください。

次に、 redis サービス定義:

〜/ rails-docker / docker-compose.yml
. . .
  redis:
    image: redis:5.0.7

以下のような database サービス、 redis サービスはDockerHubのイメージを使用します。 この場合、Sidekiqジョブキャッシュを永続化することはありません。

最後に、 sidekiq サービス定義:

〜/ rails-docker / docker-compose.yml
. . .
  sidekiq:
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
      - app      
      - database
      - redis
    volumes:
      - .:/app
      - gem_cache:/usr/local/bundle/gems
      - node_modules:/app/node_modules
    env_file: .env
    environment:
      RAILS_ENV: development
    entrypoint: ./entrypoints/sidekiq-entrypoint.sh

私たちの sidekiq サービスは私たちに似ています app いくつかの点でサービス:同じビルドコンテキストとイメージ、環境変数、およびボリュームを使用します。 ただし、 app, redis、 と database サービスなどが最後に開始されます。 さらに、それは使用します entrypoint これにより、Dockerfileで設定されたエントリポイントが上書きされます。 これ entrypoint 設定ポイント entrypoints/sidekiq-entrypoint.sh、これには、を開始するための適切なコマンドが含まれています sidekiq サービス。

最後のステップとして、ボリューム定義を以下に追加します。 sidekiq サービス定義:

〜/ rails-docker / docker-compose.yml
. . .
volumes:
  gem_cache:
  db_data:
  node_modules:

トップレベルのボリュームキーはボリュームを定義します gem_cache, db_data、 と node_modules. Dockerがボリュームを作成すると、ボリュームのコンテンツはホストファイルシステムの一部に保存されます。 /var/lib/docker/volumes/、それはDockerによって管理されています。 各ボリュームの内容は、下のディレクトリに保存されます /var/lib/docker/volumes/ ボリュームを使用する任意のコンテナにマウントされます。 このようにして、ユーザーが作成するサメの情報データは、 db_data 削除して再作成してもボリューム database サービス。

完成したファイルは次のようになります。

〜/ rails-docker / docker-compose.yml
version: '3.4'

services:
  app: 
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:     
      - database
      - redis
    ports: 
      - "3000:3000"
    volumes:
      - .:/app
      - gem_cache:/usr/local/bundle/gems
      - node_modules:/app/node_modules
    env_file: .env
    environment:
      RAILS_ENV: development

  database:
    image: postgres:12.1
    volumes:
      - db_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql

  redis:
    image: redis:5.0.7

  sidekiq:
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
      - app      
      - database
      - redis
    volumes:
      - .:/app
      - gem_cache:/usr/local/bundle/gems
      - node_modules:/app/node_modules
    env_file: .env
    environment:
      RAILS_ENV: development
    entrypoint: ./entrypoints/sidekiq-entrypoint.sh

volumes:
  gem_cache:
  db_data:
  node_modules:     

編集が終了したら、ファイルを保存して閉じます。

サービス定義を記述したら、アプリケーションを開始する準備が整います。

ステップ5—アプリケーションのテスト

あなたと docker-compose.yml ファイルを配置したら、 docker-compose up コマンドを使用してサービスを作成し、データベースをシードできます。 docker-compose down を使用してコンテナーを停止および削除し、それらを再作成することで、データが保持されることをテストすることもできます。

まず、コンテナイメージを構築し、を実行してサービスを作成します docker-compose up とともに -d フラグ。コンテナをバックグラウンドで実行します。

  1. docker-compose up -d

サービスが作成されたという出力が表示されます。

Output
Creating rails-docker_database_1 ... done Creating rails-docker_redis_1 ... done Creating rails-docker_app_1 ... done Creating rails-docker_sidekiq_1 ... done

また、サービスからのログ出力を表示することにより、起動プロセスに関するより詳細な情報を取得できます。

  1. docker-compose logs

すべてが正しく開始されている場合は、次のように表示されます。

Output
sidekiq_1 | 2019-12-19T15:05:26.365Z pid=6 tid=grk7r6xly INFO: Booting Sidekiq 6.0.3 with redis options {:host=>"redis", :port=>"6379", :id=>"Sidekiq-server-PID-6", :url=>nil} sidekiq_1 | 2019-12-19T15:05:31.097Z pid=6 tid=grk7r6xly INFO: Running in ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-musl] sidekiq_1 | 2019-12-19T15:05:31.097Z pid=6 tid=grk7r6xly INFO: See LICENSE and the LGPL-3.0 for licensing details. sidekiq_1 | 2019-12-19T15:05:31.097Z pid=6 tid=grk7r6xly INFO: Upgrade to Sidekiq Pro for more features and support: http://sidekiq.org app_1 | => Booting Puma app_1 | => Rails 5.2.3 application starting in development app_1 | => Run `rails server -h` for more startup options app_1 | Puma starting in single mode... app_1 | * Version 3.12.1 (ruby 2.5.1-p57), codename: Llamas in Pajamas app_1 | * Min threads: 5, max threads: 5 app_1 | * Environment: development app_1 | * Listening on tcp://0.0.0.0:3000 app_1 | Use Ctrl-C to stop . . . database_1 | PostgreSQL init process complete; ready for start up. database_1 | database_1 | 2019-12-19 15:05:20.160 UTC [1] LOG: starting PostgreSQL 12.1 (Debian 12.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit database_1 | 2019-12-19 15:05:20.160 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 database_1 | 2019-12-19 15:05:20.160 UTC [1] LOG: listening on IPv6 address "::", port 5432 database_1 | 2019-12-19 15:05:20.163 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" database_1 | 2019-12-19 15:05:20.182 UTC [63] LOG: database system was shut down at 2019-12-19 15:05:20 UTC database_1 | 2019-12-19 15:05:20.187 UTC [1] LOG: database system is ready to accept connections . . . redis_1 | 1:M 19 Dec 2019 15:05:18.822 * Ready to accept connections

docker-compose ps を使用して、コンテナーのステータスを確認することもできます。

  1. docker-compose ps

コンテナが実行されていることを示す出力が表示されます。

Output
Name Command State Ports ----------------------------------------------------------------------------------------- rails-docker_app_1 ./entrypoints/docker-resta ... Up 0.0.0.0:3000->3000/tcp rails-docker_database_1 docker-entrypoint.sh postgres Up 5432/tcp rails-docker_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp rails-docker_sidekiq_1 ./entrypoints/sidekiq-entr ... Up

次に、データベースを作成してシードし、次のdocker-composeexecコマンドを使用してデータベースで移行を実行します。

  1. docker-compose exec app bundle exec rake db:setup db:migrate

The docker-compose exec commandを使用すると、サービスでコマンドを実行できます。 ここで実行するために使用しています rake db:setupdb:migrate アプリケーションバンドルのコンテキストで、データベースを作成してシードし、移行を実行します。 開発に取り組むとき、 docker-compose exec 開発データベースに対して移行を実行する場合に役立ちます。

このコマンドを実行すると、次の出力が表示されます。

Output
Created database 'rails_development' Database 'rails_development' already exists -- enable_extension("plpgsql") -> 0.0140s -- create_table("endangereds", {:force=>:cascade}) -> 0.0097s -- create_table("posts", {:force=>:cascade}) -> 0.0108s -- create_table("sharks", {:force=>:cascade}) -> 0.0050s -- enable_extension("plpgsql") -> 0.0173s -- create_table("endangereds", {:force=>:cascade}) -> 0.0088s -- create_table("posts", {:force=>:cascade}) -> 0.0128s -- create_table("sharks", {:force=>:cascade}) -> 0.0072s

あなたのサービスが実行されていると、あなたは訪問することができます localhost:3000 また http://your_server_ip:3000 ブラウザで。 次のようなランディングページが表示されます。

これで、データの永続性をテストできます。 Get Shark Info ボタンをクリックして、新しいサメを作成します。 sharks/index ルート:

アプリケーションが機能していることを確認するために、いくつかのデモ情報をアプリケーションに追加できます。 NewSharkをクリックします。 プロジェクトの認証設定のおかげで、ユーザー名( sammy )とパスワード( shark )の入力を求められます。

New Shark ページで、 Name フィールドに「Mako」を入力し、Factsフィールドに「Fast」を入力します。

サメの作成ボタンをクリックしてサメを作成します。 サメを作成したら、サイトのナビゲーションバーでホームをクリックして、メインのアプリケーションランディングページに戻ります。 これで、Sidekiqが機能していることをテストできます。

どのサメが危険にさらされていますか?ボタンをクリックします。 絶滅危惧種のサメをアップロードしていないので、 endangered index 見る:

絶滅危惧種のサメのインポートをクリックして、サメをインポートします。 サメが輸入されたことを知らせるステータスメッセージが表示されます。

インポートの開始も表示されます。 ページを更新して、テーブル全体を表示します。

Sidekiqのおかげで、絶滅危惧種のサメの大量のバッチアップロードは、ブラウザをロックしたり、他のアプリケーション機能に干渉したりすることなく成功しました。

ページの下部にあるホームボタンをクリックすると、アプリケーションのメインページに戻ります。

ここから、どのサメが危険にさらされていますか?をもう一度クリックします。 アップロードされたサメがもう一度表示されます。

アプリケーションが正しく機能していることがわかったので、データの永続性をテストできます。

ターミナルに戻り、次のコマンドを入力して、コンテナを停止して削除します。

  1. docker-compose down

は含まれていないことに注意してください --volumes オプション; したがって、私たちの db_data ボリュームは削除されません。

次の出力は、コンテナとネットワークが削除されたことを確認します。

Output
Stopping rails-docker_sidekiq_1 ... done Stopping rails-docker_app_1 ... done Stopping rails-docker_database_1 ... done Stopping rails-docker_redis_1 ... done Removing rails-docker_sidekiq_1 ... done Removing rails-docker_app_1 ... done Removing rails-docker_database_1 ... done Removing rails-docker_redis_1 ... done Removing network rails-docker_default

コンテナを再作成します。

  1. docker-compose up -d

でRailsコンソールを開きます app コンテナ docker-compose execbundle exec rails console:

  1. docker-compose exec app bundle exec rails console

プロンプトで、 last データベース内のサメの記録:

  1. Shark.last.inspect

作成したばかりのレコードが表示されます。

IRB session
Shark Load (1.0ms) SELECT "sharks".* FROM "sharks" ORDER BY "sharks"."id" DESC LIMIT $1 [["LIMIT", 1]] => "#<Shark id: 5, name: \"Mako\", facts: \"Fast\", created_at: \"2019-12-20 14:03:28\", updated_at: \"2019-12-20 14:03:28\">"

次に、あなたの Endangered サメは次のコマンドで持続しました:

  1. Endangered.all.count
IRB session
(0.8ms) SELECT COUNT(*) FROM "endangereds" => 73

君の db_data ボリュームは再作成されたものに正常にマウントされました database サービス、あなたのためにそれを可能にします app 保存されたデータにアクセスするサービス。 に直接移動する場合 index shark にアクセスしてページ localhost:3000/sharks また http://your_server_ip:3000/sharks また、そのレコードが表示されます。

あなたの絶滅危惧種のサメも localhost:3000/endangered/data また http://your_server_ip:3000/endangered/data 見る:

これで、アプリケーションは、データの永続性とコードの同期が有効になっているDockerコンテナで実行されます。 先に進んで、ホストでローカルコードの変更をテストできます。これは、の一部として定義したバインドマウントのおかげで、コンテナーに同期されます。 app サービス。

結論

このチュートリアルに従うことで、Dockerコンテナーを使用してRailsアプリケーションの開発セットアップを作成しました。 機密情報を抽出し、アプリケーションの状態をコードから切り離すことで、プロジェクトをよりモジュラーでポータブルにしました。 ボイラープレートも構成しました docker-compose.yml 開発のニーズや要件の変化に応じて修正できるファイル。

開発するにつれて、コンテナ化された CloudNativeワークフロー用のアプリケーションの設計についてさらに学ぶことに興味があるかもしれません。 これらのトピックの詳細については、Kubernetes用アプリケーションのアーキテクチャおよびKubernetes用アプリケーションの最新化を参照してください。 または、Kubernetesの学習シーケンスに投資したい場合は、フルスタック開発者向けKubernetesカリキュラムをご覧ください。

アプリケーションコード自体の詳細については、このシリーズの他のチュートリアルを参照してください。