DockerComposeを使用した開発のためのRubyonRailsアプリケーションのコンテナー化
序章
アプリケーションを積極的に開発している場合は、 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
:
- git clone https://github.com/do-community/rails-sidekiq.git rails-docker
に移動します rails-docker
ディレクトリ:
- cd rails-docker
このチュートリアルでは、PostgreSQLをデータベースとして使用します。 SQLite 3の代わりにPostgreSQLを使用するには、Gemfileにリストされているプロジェクトの依存関係に pggemを追加する必要があります。 を使用して編集するためにそのファイルを開きます nano
またはお気に入りの編集者:
- nano Gemfile
メインプロジェクトの依存関係(開発の依存関係の上)の任意の場所にgemを追加します。
. . .
# 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 はもう使用しないため、コメントアウトすることもできます。
. . .
# Use sqlite3 as the database for Active Record
# gem 'sqlite3'
. . .
最後に、 spring-watcher-listengemをコメントアウトします。 development
:
. . .
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
プロジェクトのファイルおよびその他の関連ファイルgitignore
とdockerignore
ファイル。 - データベースシードを作成して、アプリケーションの起動時に使用できるレコードがアプリケーションに含まれるようにします。
まず、次の場所にあるデータベース構成ファイルを開きます。 config/database.yml
:
- nano config/database.yml
現在、ファイルには次のものが含まれています default
他の設定がない場合に適用される設定:
default: &default
adapter: sqlite3
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000
を使用するという事実を反映するために、これらを変更する必要があります postgresql
アプリケーションデータを永続化するためにDockerComposeを使用してPostgreSQLサービスを作成するためです。
SQLiteをアダプターとして設定するコードを削除し、次の設定に置き換えます。これにより、アダプターと接続に必要なその他の変数が適切に設定されます。
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データベース構成を削除します。
. . .
development:
<<: *default
. . .
最後に、 database
の設定 production
と test
環境も:
. . .
test:
<<: *default
production:
<<: *default
. . .
デフォルトのデータベース設定に対するこれらの変更により、で定義された環境変数を使用してデータベース情報を動的に設定できるようになります。 .env
バージョン管理にコミットされないファイル。
編集が終了したら、ファイルを保存して閉じます。
Railsプロジェクトを最初から作成する場合は、アダプターを次のように設定できることに注意してください。 rails new
Ubuntu18.04上のRubyonRailsアプリケーションでPostgreSQLを使用する方法のステップ3で説明されているコマンド。 これにより、アダプタがに設定されます config/database.yml
自動的に追加します pg
プロジェクトへの宝石。
環境変数を参照したので、好みの設定でそれらのファイルを作成できます。 この方法で構成設定を抽出することは、アプリケーション開発への 12ファクターアプローチの一部であり、分散環境でのアプリケーションの復元力のベストプラクティスを定義します。 現在、将来的に本番環境とテスト環境をセットアップする場合、データベース設定の構成には追加の作成が含まれます .env
ファイルとDockerComposeファイル内の適切なファイルの参照。
開く .env
ファイル:
- nano .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
起動時にデータベースコンテナにマウントできるスクリプト。
スクリプトファイルを開きます。
- nano init.sql
次のコードを追加して、 sammy
管理者権限を持つユーザー:
CREATE USER sammy;
ALTER USER sammy WITH SUPERUSER;
このスクリプトは、データベース上に適切なユーザーを作成し、このユーザーに管理者権限を付与します。
スクリプトに適切な権限を設定します。
- chmod +x init.sql
次に、コンテナ化されたコンテナで動作するようにSidekiqを構成します redis
サービス。 イニシャライザを追加できます config/initializers
フレームワークとプラグインがロードされるとRailsが構成設定を探すディレクトリ。Redisホストの値を設定します。
開く sidekiq.rb
これらの設定を指定するファイル:
- nano config/initializers/sidekiq.rb
次のコードをファイルに追加して、 REDIS_HOST
と REDIS_PORT
:
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に指示します。 編集用にファイルを開きます。
- nano .gitignore
ファイルの下部に、次のエントリを追加します .env
:
yarn-debug.log*
.yarn-integrity
.env
編集が終了したら、ファイルを保存して閉じます。
次に、を作成します .dockerignore
コンテナにコピーしないものを設定するファイル。 編集用にファイルを開きます。
- .dockerignore
次のコードをファイルに追加します。これにより、Dockerは、コンテナーにコピーする必要のないものの一部を無視するようになります。
.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
このファイルの最後にも:
. . .
yarn-error.log
coverage/
.env
編集が終了したら、ファイルを保存して閉じます。
最後のステップとして、アプリケーションを起動したときにいくつかのレコードが含まれるように、いくつかのシードデータを作成します。
シードデータのファイルを開きます db
ディレクトリ:
- nano db/seeds.rb
次のコードをファイルに追加して、4つのデモサメと1つのサンプル投稿を作成します。
# 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を開きます。
- nano Dockerfile
Dockerイメージは、相互に構築される一連のレイヤードイメージを使用して作成されます。 最初のステップは、アプリケーションのベースイメージを追加することです。これにより、アプリケーションビルドの開始点が形成されます。
次のコードをファイルに追加して、 Ruby alpineimageをベースとして追加します。
FROM ruby:2.5.1-alpine
The alpine
imageはAlpineLinuxプロジェクトから派生しており、画像サイズを小さく抑えるのに役立ちます。 かどうかの詳細については alpine
画像はプロジェクトに適した選択です。DockerHubRuby画像ページの画像バリアントセクションの詳細な説明を参照してください。
使用する際に考慮すべきいくつかの要因 alpine
開発中:
- 画像サイズを小さくすると、特にボリュームを最小限に抑える場合は、ページとリソースの読み込み時間が短縮されます。 これにより、開発におけるユーザーエクスペリエンスを迅速に保ち、コンテナ化されていない環境でローカルで作業している場合のエクスペリエンスに近づけることができます。
- 開発イメージと本番イメージの間に同等性があると、展開の成功が容易になります。 チームはスピードのメリットのために本番環境でアルパインイメージを使用することを選択することが多いため、アルパインベースで開発すると、本番環境に移行する際の問題を相殺するのに役立ちます。
次に、環境変数を設定して、Bundlerバージョンを指定します。
. . .
ENV BUNDLER_VERSION=2.0.2
これは、デフォルト間のバージョンの競合を回避するために実行する手順の1つです。 bundler
私たちの環境で利用可能なバージョンと、Bundler2.0.2を必要とするアプリケーションコード。
次に、アプリケーションでの作業に必要なパッケージを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
これらのパッケージには次のものが含まれます nodejs
と yarn
、とりわけ。 アプリケーションはwebpackでアセットを提供するため、アプリケーションが期待どおりに機能するには、Node.jsとYarnを含める必要があります。
覚えておいてください alpine
イメージは非常に最小限です。ここにリストされているパッケージは、独自のアプリケーションをコンテナー化するときに開発で必要になる可能性のあるものを網羅しているわけではありません。
次に、適切なをインストールします bundler
バージョン:
. . .
RUN gem install bundler -v 2.0.2
この手順により、コンテナ化された環境とこのプロジェクトの仕様との同等性が保証されます。 Gemfile.lock
ファイル。
次に、コンテナにアプリケーションの作業ディレクトリを設定します。
. . .
WORKDIR /app
あなたの Gemfile
と Gemfile.lock
:
. . .
COPY Gemfile Gemfile.lock ./
これらのファイルを独立した手順としてコピーし、その後に bundle install
は、アプリケーションコードに変更を加えるたびにプロジェクトgemを再構築する必要がないことを意味します。 これは、Composeファイルに含めるgemボリュームと連携して機能します。このボリュームは、サービスが再作成されてもプロジェクトgemが同じである場合に、アプリケーションコンテナーにgemをマウントします。
次に、の構成オプションを設定します nokogiri
ジェムビルド:
. . .
RUN bundle config build.nokogiri --use-system-libraries
. . .
このステップはビルドします nokigiri
libxml2およびlibxsltライブラリバージョンを使用してアプリケーションコンテナに追加しました RUN apk add…
上記のステップ。
次に、プロジェクトgemをインストールします。
. . .
RUN bundle check || bundle install
この手順では、gemをインストールする前に、gemがまだインストールされていないことを確認します。
次に、JavaScriptパッケージと依存関係を使用してgemで使用したのと同じ手順を繰り返します。 最初にパッケージメタデータをコピーし、次に依存関係をインストールし、最後にアプリケーションコードをコンテナイメージにコピーします。
DockerfileのJavascriptセクションを開始するには、次のようにコピーします。 package.json
と yarn.lock
ホスト上の現在のプロジェクトディレクトリからコンテナへ:
. . .
COPY package.json yarn.lock ./
次に、必要なパッケージをでインストールします yarn install
:
. . .
RUN yarn install --check-files
この指示には、 --check-files
フラグ yarn
コマンド、以前にインストールされたファイルが削除されていないことを確認する機能。 私たちの宝石の場合のように、私たちはパッケージの永続性を管理します node_modules
Composeファイルを書き込むときのボリュームのあるディレクトリ。
最後に、残りのアプリケーションコードをコピーして、エントリポイントスクリプトを使用してアプリケーションを起動します。
. . .
COPY . ./
ENTRYPOINT ["./entrypoints/docker-entrypoint.sh"]
エントリポイントスクリプトを使用すると、コンテナを実行可能ファイルとして実行できます。
最終的な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
エントリポイントスクリプトの場合:
- mkdir entrypoints
このディレクトリには、メインのエントリポイントスクリプトとSidekiqサービスのスクリプトが含まれます。
アプリケーションエントリポイントスクリプトのファイルを開きます。
- nano 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
.
編集が終了したら、ファイルを保存して閉じます。
スクリプトを実行可能にします。
- chmod +x entrypoints/docker-entrypoint.sh
次に、スクリプトを作成して開始します sidekiq
Sidekiqジョブを処理するサービス。 このアプリケーションがSidekiqを使用する方法の詳細については、SidekiqとRedisをRubyonRailsアプリケーションに追加する方法を参照してください。
Sidekiqエントリポイントスクリプトのファイルを開きます。
- nano entrypoints/sidekiq-entrypoint.sh
Sidekiqを起動するには、ファイルに次のコードを追加します。
#!/bin/sh
set -e
if [ -f tmp/pids/server.pid ]; then
rm tmp/pids/server.pid
fi
bundle exec sidekiq
このスクリプトは、アプリケーションバンドルのコンテキストでSidekiqを起動します。
編集が終了したら、ファイルを保存して閉じます。 実行可能にする:
- 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
ファイル:
- nano 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
:これは、以下を含む構成オプションを定義します。context
とdockerfile
、これは、Composeがアプリケーションイメージをビルドするときに適用されます。 Docker Hub などのレジストリの既存のイメージを使用する場合は、代わりに image命令を使用して、ユーザー名、リポジトリ、イメージタグに関する情報を使用できます。context
:これは、イメージビルドのビルドコンテキスト(この場合は現在のプロジェクトディレクトリ)を定義します。dockerfile
:これはDockerfile
Composeがアプリケーションイメージのビルドに使用するファイルとして、現在のプロジェクトディレクトリにあります。depends_on
:これはdatabase
とredis
最初にコンテナを稼働させてから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
ホストにマウントされると、開発中にパッケージの不一致や権限の競合が発生する可能性があります。このボリュームは、このディレクトリ内のパッケージが永続化され、プロジェクトの現在の状態を反映することを保証します。 この場合も、プロジェクトのノード依存関係を変更する場合は、このボリュームを削除して再作成する必要があります。
- 1つ目は、 bind mount で、ホスト上のアプリケーションコードをにマウントします。
env_file
:これは、Composeに、というファイルから環境変数を追加することを通知します。.env
ビルドコンテキストにあります。environment
:このオプションを使用すると、機密性の低い環境変数を設定して、Rails環境に関する情報をコンテナに渡すことができます。
次に、以下 app
サービス定義、次のコードを追加して、 database
サービス:
. . .
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
サービス定義:
. . .
redis:
image: redis:5.0.7
以下のような database
サービス、 redis
サービスはDockerHubのイメージを使用します。 この場合、Sidekiqジョブキャッシュを永続化することはありません。
最後に、 sidekiq
サービス定義:
. . .
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
サービス定義:
. . .
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
サービス。
完成したファイルは次のようになります。
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
フラグ。コンテナをバックグラウンドで実行します。
- docker-compose up -d
サービスが作成されたという出力が表示されます。
OutputCreating rails-docker_database_1 ... done
Creating rails-docker_redis_1 ... done
Creating rails-docker_app_1 ... done
Creating rails-docker_sidekiq_1 ... done
また、サービスからのログ出力を表示することにより、起動プロセスに関するより詳細な情報を取得できます。
- docker-compose logs
すべてが正しく開始されている場合は、次のように表示されます。
Outputsidekiq_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 を使用して、コンテナーのステータスを確認することもできます。
- 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コマンドを使用してデータベースで移行を実行します。
- docker-compose exec app bundle exec rake db:setup db:migrate
The docker-compose exec
commandを使用すると、サービスでコマンドを実行できます。 ここで実行するために使用しています rake db:setup
と db:migrate
アプリケーションバンドルのコンテキストで、データベースを作成してシードし、移行を実行します。 開発に取り組むとき、 docker-compose exec
開発データベースに対して移行を実行する場合に役立ちます。
このコマンドを実行すると、次の出力が表示されます。
OutputCreated 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のおかげで、絶滅危惧種のサメの大量のバッチアップロードは、ブラウザをロックしたり、他のアプリケーション機能に干渉したりすることなく成功しました。
ページの下部にあるホームボタンをクリックすると、アプリケーションのメインページに戻ります。
ここから、どのサメが危険にさらされていますか?をもう一度クリックします。 アップロードされたサメがもう一度表示されます。
アプリケーションが正しく機能していることがわかったので、データの永続性をテストできます。
ターミナルに戻り、次のコマンドを入力して、コンテナを停止して削除します。
- docker-compose down
は含まれていないことに注意してください --volumes
オプション; したがって、私たちの db_data
ボリュームは削除されません。
次の出力は、コンテナとネットワークが削除されたことを確認します。
OutputStopping 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
コンテナを再作成します。
- docker-compose up -d
でRailsコンソールを開きます app
コンテナ docker-compose exec
と bundle exec rails console
:
- docker-compose exec app bundle exec rails console
プロンプトで、 last
データベース内のサメの記録:
- 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
サメは次のコマンドで持続しました:
- 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カリキュラムをご覧ください。
アプリケーションコード自体の詳細については、このシリーズの他のチュートリアルを参照してください。