既存のRailsアプリケーションのコンテナ化
コンテナ化ソフトウェアは、開発と展開を容易にするために、標準化されたユニットにパッケージ化しています。コンテナは、アプリケーションのコードとそのすべての依存関係をバンドルします。コンテナは完全にスタンドアロンにすることができます。これには、ソフトウェア、ランタイム環境、およびシステムライブラリを含むパッケージが含まれています。コンテナは、開発者と運用チームが、環境に関係なく、ソフトウェアが同じように実行されることを保証するのに役立ちます。コードをインフラストラクチャから分離することで、「コンテナ化」されたアプリは、ローカル環境、テスト環境、本番環境で同じように実行されます。
Dockerは、ソフトウェアを開発およびデプロイするための最も人気のあるプラットフォームの1つです。 Dockerは、ソフトウェアを「イメージ」としてパッケージ化します。これは、Dockerイメージで実行されると、実行時にコンテナーに変換されます。分離により、開発者は単一のホストで同時に多くのコンテナーを実行できます。
Railsの開発者は、既存のアプリケーションをコンテナ化するときに、独自の一連の課題に直面します。この記事では、機能的なRailsアプリをコンテナー化するためのウォークスルーを提供し、その過程で重要な概念と落とし穴について説明します。この記事は、コンテナーまたはDockerの基本的な説明ではありません。代わりに、本番アプリケーションをコンテナ化するときに開発者が直面する問題の説明です。
フォローしている場合は、まだドッキングされていないRailsアプリケーションが必要になることは明らかです(これは、「コンテナー化」のDocker固有の用語です)。私は、完全な機能を備えたサイドプロジェクトであるRailsWorkを使用します。発売。 Railsで作成され、Herokuにデプロイされた求人掲示板ですが、コンテナ化されていません。
それ以外にも、Dockerをインストールする必要があります。インストールする一般的な方法は、公式WebサイトからダウンロードできるDockerデスクトップを使用することです。
アプリがダウンロードされたら、インストーラーを実行します。実行後、アプリケーションをアプリケーションフォルダにドラッグするように求められます。次に、アプリケーションフォルダからアプリを起動する必要があります 要求された特権権限を付与します。 Dockerが正しくインストールされていることを確認する最後のチェックとして、次のコマンドを実行して、端末からマシンで実行されているコンテナーを一覧表示してみてください。
docker ps
Dockerがインストールされている場合(そしてコンテナーを実行していない場合)、次のようなヘッダーのみを含む空のリストが表示されます。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Dockerfile
深く掘り下げる前に、明確な用語から始めることが重要です。
Railsアプリケーションが「Dockerized」されると、コンテナで実行されます。 。コンテナはスタンドアロンで、交換可能で、多くの場合再構築されます。
コンテナは画像から構築されます 。イメージは、メタデータとペアになったファイルシステムの仮想スナップショットです。
Dockerfile 画像の作成方法を説明するソースコードです。 Dockerfileは、Docker化されたアプリのリポジトリに含まれ、アプリの他の部分と一緒にバージョン管理で追跡されることがよくあります。
Dockerfileの作成は、思ったより簡単です。 Dockerは、何かをコンテナー化するという大変な作業を抽象化する特別な構文を提供します。まず、コンテナ化するアプリのルートディレクトリに移動します。作業を開始する準備ができたので、gitを使用している場合は、新しいブランチを作成することをお勧めします。 dockerize-this-app
という名前の新しいブランチを簡単に作成できます 次のコマンドを実行します:
git checkout -b dockerize-this-app
次に、Dockerfileを作成し、Rubyアプリケーションに基づいてイメージを構築するように指示します。これは、コマンドラインから次のコマンドを実行して実行できます。
echo "FROM ruby:3.0.0" > Dockerfile
ここでは、Dockerfileを作成し、Rubyコンテナイメージの場所を指定する行を追加しています。私のプロジェクトはRuby3.0.0を使用しているので、適切なイメージを使用しました。別のバージョンのRubyを使用している場合は、問題ありません。 Dockerには、サポートされているすべてのイメージのリストがあります。
次に、DockerにDockerイメージを作成するように手動で指示します。
docker build -t rails_work .
ここで、rails_work
を置き換えることができます 画像に任意の名前を付けます。また、必ず最後にピリオドを含めてください!
イメージが作成されたことを確認したい場合は、次の方法でシステム上のイメージを一覧表示できます。
docker image list
ただし、この画像はほとんど空です。現在、アプリケーションは含まれていません。 Dockerfileの最後に以下を追加することで、アプリからコードを追加するように指示できます。
ADD . /rails_work
WORKDIR /rails_work
RUN bundle install
これにより、アプリケーションからファイルがコピーされ、アプリケーションの依存関係がインストールされます。 (ここでは、rails_work
を置き換えます アプリの名前で。)
この時点で、コマンドを再実行してイメージを作成する必要があります。
docker image list
ここに問題が発生する可能性があります 特に、既存の本番アプリケーションに対してこれを行う場合。 Bundlerは、イメージが使用しようとしているBundlerのバージョンが、Gemfile.lock
を作成したバージョンとは異なると文句を言う場合があります。 ファイル。これが発生した場合、2つの明確なオプションがあります:
- 画像が使用しているバージョンを変更します。
-
Gemfile.lock
を削除します 全体的に。 **これを行う場合は、ロックファイルが完全に再生成されるため、特定のバージョンで必要なGemsのバージョンを固定してください。
それでもバンドルのインストールが失敗する場合は、Dockerfileに追加のインストールが必要になる場合があります :
RUN apt-get update && apt-get install -y shared-mime-info
それでも問題が発生する場合は、ベースとなる間違ったRubyイメージを選択した可能性があります 、そこで調査を開始する価値があります。
これは、環境変数を設定する良い機会です。 :
ENV RAILS_ENV production
ENV RAILS_SERVE_STATIC_FILES true
次に、Railsがデフォルトで実行されるポート3000を公開する行を追加します。
EXPOSE 3000
最後に、起動時にbashシェルを開くようにコンテナに指示します。
CMD ["bash"]
全体として、Dockerfileは次のようになります(rails_work名が置き換えられます):
FROM ruby:3.0.0
ADD . /rails_work
WORKDIR /rails_work
RUN bundle install
ENV RAILS_ENV production
ENV RAILS_SERVE_STATIC_FILES true
EXPOSE 3000
CMD ["bash"]
最も一般的なDockerfileコマンドのいくつかを完全に理解しておくと確かに役立ちます。
- FROM->これは、ベースとなる画像を定義します。
- RUN->これは内部のコマンドを実行します コンテナ。
- ENV->これは環境変数を定義します。
- WORKDIR->これにより、コンテナが使用しているディレクトリが変更されます。
- CMD->コンテナの起動時に実行するプログラムを指定します。
Dockerのドキュメントによると、「作成」は、複数のDockerコンテナーを使用してアプリケーションを作成(および起動)するためのツールです。アプリケーションに必要なコンテナーを起動するために必要なものはすべて、YAMLで概説されています。誰かがdocker-compose up
を実行したとき 、コンテナが作成されます! Docker-composeを使用すると、コンテナー構成を宣言的に記述できます。
Docker Composeファイルを作成する前に、ビルドされるイメージからどのファイルを除外する必要があるかをDockerに示すことが重要です。 .dockerignore
というファイルを作成します 。 (ピリオドに注意してください!)このファイルに、以下を貼り付けます:
.git
.dockerignore
.env
Gemfileがビルドプロセスによって維持されている場合は、必ずGemfile.lock
を追加してください。 上記の無視に。
次に、docker-compose.yml
というファイルを作成します 。ここで、コンテナの構成について説明します。ファイルの内容については、これから始めます:
version: '3.8'
services:
db:
image: postgres
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
volumes:
- postgres:/var/lib/postgresql/data
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/Rails-Docker
ports:
- "3000:3000"
depends_on:
- db
volumes:
postgres:
このファイルは2つのサービスを作成します。1つはdb
と呼ばれます もう1つはweb
と呼ばれます 。 dbコンテナは、postgres用に作成されたイメージから構築されるため、POSTGRES_USER
の関連する値を置き換える必要があります。 およびPOSTGRES_PASSWORD
。 制作の秘密を入れないように注意する このファイルの内容-詳細については、以下の「秘密の管理」セクションを参照してください。
WebコンテナはDockerfileから構築され、IPアドレス0.0.0.0のポート3000でRailsサーバーを起動します。次に、内部ポート3000が実際のポート3000にマップされます。
そして最後に、データを永続化するためのPostgresボリュームがあります。
ビルド時の認証は、実稼働アプリケーションでは問題になる可能性があります。おそらく、アプリケーションがプライベートリポジトリからGemsを探しているか、データベースのクレデンシャルを保存する必要があるだけです。
Dockerfileに直接含まれる情報はすべて、コンテナイメージに永久に焼き付けられます。これは、一般的なセキュリティの落とし穴です。
Railsのクレデンシャルマネージャーを使用している場合、Docker(またはそのことについては任意のホスト)にアクセスを許可することは比較的簡単です。 Docker Composeファイルでは、RAILS_MASTER_KEY
を指定するだけです。 環境変数。指定された作成ターゲットに対して、environment
の下でキーを指定します ヘッダー。まだ作成していない場合は作成する必要があります。上からのdocker-composeファイルは次のようになります:
version: '3.8'
services:
db:
image: postgres
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
volumes:
- postgres:/var/lib/postgresql/data
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/Rails-Docker
ports:
- "3000:3000"
depends_on:
- db
environment:
- RAILS_MASTER_KEY=this_would_be_the_key
volumes:
postgres:
さて、これはあなたを岐路に立たせます。このファイルをソース管理にコミットすることをお勧めしますが、ソース管理によってマスターキーやデータベースパスワードを追跡することは絶対に望まない 、これは別の危険なセキュリティ問題になるためです。これまでの最善の解決策は、dotenv gemを利用して、プロキシでこれらのクレデンシャルにアクセスし、別のファイルに保存できるようにすることです。 ソース管理では追跡されません。
Dockerizedアプリケーションの実行
最後に、次のコマンドを使用してドッキングされたアプリケーションを実行できます。
docker compose up
信じられないかもしれませんが、それだけです。 Docker-composeを使用すると、特にコマンドライン引数に関して、コンテナーを簡単に起動できます。
実行中のコンテナのリストが必要な場合は、次を実行するだけです。
docker ps
Railsコンテナ名がweb
の場合 、かなり簡単な方法でコマンドを実行できます。たとえば、Railsコンソールを実行する場合は、次を実行するだけです。
docker exec -it web rails console
コンテナ内にbashシェルが必要な場合は、代わりに次を実行します。
docker exec -it web bash
本番環境でのドッキングされたRailsアプリケーションの一般的な問題の1つは、ログの処理です。それらは、コンテナシステムに長期間存在するべきではありません。 Dockerは、ログを単にSTDOUTにリダイレクトすることを提案しています。これは、config/application.rb
で明示的に構成できます。 。
もう1つの一般的な問題は、メーラーの問題です。アプリケーションでメーラーを使用する場合は、接続設定を明示的に定義する必要があります 。 SMTPは完全に優れた配信方法であり、通常はデフォルトで適切に機能しますが、サーバーの場所やその他の設定をコンテナの構成と一致するように注意深く設定する必要があります。
sidekiqなどの労働者またはバックグラウンドの仕事がある場合 、次にそれを独自のコンテナで実行する必要があります。
確かに見てきたように、本番Railsアプリケーションのコンテナー化には一連の課題が伴います。アプリケーションが成長するにつれて、このような移行を困難にする多くの依存関係が蓄積されている可能性があります。バックグラウンドワーカー、メーラー、シークレットのいずれであっても、ほとんどの落とし穴を処理するための確立されたパターンがあります。本番アプリケーションをDockerで動作させるための最初の作業が完了すると、将来の変更とデプロイが容易になるため、投資する価値があります。
-
Rails5でのAngularの使用
あなたは前にその話を聞いたことがあります。分散型で完全に機能するバックエンドAPIと、通常のツールセットで作成されたフロントエンドで実行されているアプリケーションがすでにあります。 次に、Angularに移動します。または、AngularをRailsプロジェクトと統合する方法を探しているだけかもしれません。これは、この方法を好むためです。私たちはあなたを責めません。 このようなアプローチを使用すると、両方の世界を活用して、たとえばRailsとAngularのどちらの機能を使用してフォーマットするかを決定できます。 構築するもの 心配する必要はありません。このチュートリアルは、この目的のた
-
RailsアプリケーションでOmniAuth-Twitterを使用する方法
このチュートリアルでは、アプリケーションのユーザーがTwitterアカウントを使用してログインできるようにする方法を学習します。これを行うには、OAuthなどのツールを使用すると簡単になります。 OmniAuthのTwitter戦略を含むOmniAuth-Twitterを利用します。 飛び込みましょう! はじめに Railsアプリケーションを生成することから始めます。ターミナルから、コマンドを実行して実行します。 rails new Tuts-Social -T Gemfileを開き、ブートストラップgemを追加します。 #Gemfile...gem bootstra