Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

DockerでSinatraアプリをAmazon ECS(EC2 Container Service)にデプロイする方法

告白タイムです。Honeybadgerで働き始めてから4年間、私の開発環境はほとんど変わっていませんでした。しかし、その間にHoneybadger自体は大幅に進化し、機能するために約10個ものサービスに依存するようになっていました。

そこで私たちは、ローカル開発環境をDockerへ移行することにしました。各開発者がPostgres、Cassandra、Memcachedなどを個別にセットアップする必要はなく、docker-composeを使えば、あらかじめ用意された環境をすぐに立ち上げられます。本当に快適です。

当然ながら、「Docker化したアプリを実際にデプロイするのはどれほど簡単なのだろう?」という疑問が湧いてきました。

Dockerでのデプロイ

Dockerにはdocker-machineやdocker-swarmといった、デプロイを楽にしてくれるはずのユーティリティが付属しています。しかし残念ながら、現時点ではその期待には応えていません。これらの課題については、最近のHacker Newsの投稿で詳しく議論されています。

そんなわけで、私はAmazonのECS(EC2 Container Service)に注目することにしました。

ECSとは?

ECSは、docker-composeとdocker-swarmを組み合わせて、本番運用レベルに成熟させたようなサービスです。

ECSを使えば「Webアプリを3つ実行して」と指示するだけで、クラスター内のEC2インスタンス上に適切なDockerコンテナを自動的に立ち上げてくれます。

さらに、コンテナ間でリクエストをロードバランシングしたり、負荷に応じてクラスターをスケールアップ/ダウンしたりすることも可能です。

Docker化したSinatraアプリの作成

ここでは、シンプルなSinatraアプリを例に説明します。このアプリは現在の時刻を表示するので、キャッシュされたページを見ていないかどうかがひと目でわかります。また、アプリを実行しているコンピューターの名前(ホスト名)も表示します。

後ほど、このアプリを動かす複数のサーバーを立ち上げ、ロードバランサーでリクエストを振り分けます。ホスト名を返すことで、どのサーバーが特定のリクエストを処理したのかを判別できる仕組みです。

アプリ本体

これから紹介するDocker化したSinatraアプリは、tcnksm-sample/docker-sinatraを大きく書き直したものです。

require 'sinatra'
require 'sinatra/base'

class App < Sinatra::Base
  get '/' do
    "Hello from sinatra! The time is #{ Time.now.to_i } on #{ `hostname` }!"
  end
end

続いて、Gemfileは以下の通りです。

# Gemfile
source 'https://rubygems.org'
gem 'sinatra'
gem 'thin'

そして、config.ruファイルです。

$:.unshift(File.dirname(__FILE__))
require 'app'
run App

Dockerfile

このアプリのDockerイメージを作成するには、Dockerfileが必要です。Dockerfileでは、アプリ用のディレクトリを作成し、必要なファイルをコピーし、ポート80でWebサーバーを起動するよう定義します。

FROM ruby:2.3.1-slim
RUN apt-get update -qq && apt-get install -y build-essential

ENV APP_ROOT /var/www/docker-sinatra
RUN mkdir -p $APP_ROOT
WORKDIR $APP_ROOT
ADD Gemfile* $APP_ROOT/
RUN bundle install
ADD . $APP_ROOT

EXPOSE 80
CMD ["bundle", "exec", "rackup", "config.ru", "-p", "80", "-s", "thin", "-o", "0.0.0.0"]

イメージのビルドと実行

まず、カレントディレクトリにあるDockerfileからイメージをビルドするようDockerに指示します。次にそのイメージを実行し、コンテナのポート80をlocalhost:4000にマッピングします。

docker build -t docker-sinatra .
docker run -p 4000:80 docker-sinatra

正しく動作しているか確認するには、ブラウザーでlocalhost:4000を開いてください。次のような画面が表示されるはずです。

DockerでSinatraアプリをAmazon ECS(EC2 Container Service)にデプロイする方法

ECSへのデプロイ

それでは、ECSにデプロイしていきましょう。ここでは公式のセットアップウィザードを使用します。ズルだと思いますか?気にしません :) まずはECSのコントロールパネルにアクセスしてください。

DockerでSinatraアプリをAmazon ECS(EC2 Container Service)にデプロイする方法

「Get Started(始める)」をクリックし、次の画面で「Continue(続行)」を選択します。

DockerでSinatraアプリをAmazon ECS(EC2 Container Service)にデプロイする方法

Dockerレジストリの作成

通常、開発環境から本番サーバーへ直接Dockerイメージをアップロードすることはありません。代わりに、イメージはdockerhubのようなDockerレジストリに送信し、デプロイ時にサーバー側がプルするのが一般的です。AmazonはプライベートなDockerレジストリ(ECR)を提供しており、利用は必須ではありませんが、今回はこれを使います。

レジストリ名は「docker-sinatra」としました。

DockerでSinatraアプリをAmazon ECS(EC2 Container Service)にデプロイする方法

レジストリへのイメージのプッシュ

次に、イメージをビルドしてレジストリにプッシュするためのコマンド一覧が表示されます。

ちなみに初めて試したとき、ブラウザーの広告ブロッカーのせいでコマンドが正しく表示されませんでした。変な話ですが、本当なんです。

DockerでSinatraアプリをAmazon ECS(EC2 Container Service)にデプロイする方法

タスク定義の作成

AWSは新しい紛らわしい用語を作るのが大好きです。「タスク定義(task definition)」とは、単に一緒に実行すべきコンテナのリストのことです。Procfileやdocker-composeの設定ファイルのようなものだと考えると分かりやすいでしょう。

たとえば、Nginxを動かすコンテナ、Unicornを動かすコンテナ、Sidekiqを動かすコンテナの3つがある場合、これらすべてが1つの「タスク定義」に含まれることになります。

今回のアプリはもっとシンプルで、コンテナは1つだけです。そのため設定も最小限で済みます。

  1. 正しいイメージがレジストリからプルされるように設定する
  2. コンテナのポート80を、コンテナを実行するEC2インスタンスのポート80にマッピングする

DockerでSinatraアプリをAmazon ECS(EC2 Container Service)にデプロイする方法

サービスの作成

さらに紛らわしい用語が登場します!「サービス(service)」設定では、いくつの「タスク」(いわゆるアプリのコピー)を実行するか、そしてそれらをどのようにロードバランスするかを指定できます。

ここでは、アプリを3コピー実行し、ポート80でロードバランシングするよう設定しました。

DockerでSinatraアプリをAmazon ECS(EC2 Container Service)にデプロイする方法

クラスターの起動

クラスターとは、AmazonのECSソフトウェアが稼働している、ごく普通のEC2インスタンスの集まりです。他のEC2インスタンスと同じように自由に扱えます。今回はt2.microインスタンスを3台指定しました。

いくつかの確認ステップと5分ほどの待ち時間の後、すべての準備が整いました。

サービスが正常に動作すると、次のような画面が表示されます。

DockerでSinatraアプリをAmazon ECS(EC2 Container Service)にデプロイする方法

アプリのテスト

ロードバランサー名をクリックすると詳細情報が表示されます。そこにパブリックドメイン名があるはずなので、それをブラウザーに入力すれば、サンプルアプリが表示されます。

DockerでSinatraアプリをAmazon ECS(EC2 Container Service)にデプロイする方法

何度かページを更新してみると、表示されるホスト名が変わることに気づくでしょう。これは、ロードバランサーが3台すべてのホストへリクエストを分散している証拠です。

後片付け(リソースの削除)

ECSウィザードは先ほど、AWSアカウント内に多数のリソースを作成しました。そのまま放置するのはおすすめできません。管理が煩雑になるうえ、余計なコストが発生する可能性もあります。

幸い、ECSウィザードはCloudFormationを使ってすべてのリソースを作成しています。つまり、CloudFormationスタックを削除するだけで、関連リソースをまとめて簡単に削除できるのです。

DockerでSinatraアプリをAmazon ECS(EC2 Container Service)にデプロイする方法

  1. Windows 10でアプリをミュートする方法|音量ミキサーや設定を使った5つの手順を解説

    Windows 10には、オーディオデバイスやインストール済みのさまざまなアプリの音量を細かく制御できる優れた機能が備わっています。「Windows 10でアプリをミュートするにはどうすればいいの?」とお悩みの方は、この記事が役立ちます。ヘッドホンごとに個別の音量レベルを設定でき、接続すると自動的に切り替わる仕組みも用意されています。さらに、音量ミキサーを使えば、特定のアプリだけの音量を調整することも可能です。 Windows 10でアプリをミュートする方法 PCやノートパソコンで複数のアプリを同時に実行している場合でも、それぞれの音量を簡単に管理する方法があります。音量ミキサー(Volum

  2. 偽VPNアプリを見抜く5つのヒント|本物のVPNサービスの見分け方と選び方(2022年版)

    VPN(仮想プライベートネットワーク)の世界では、本当にセキュリティを守ってくれるサービスと、まったくの中身のない偽物を見分けるのが意外と難しいのが実情です。だからこそ、詐欺的なアプリを見抜き、VPNアプリが本物かどうかを見極める力が重要になります。この記事では、偽のVPNサービスを見破るための効果的な5つのヒントをご紹介します。 「偽VPNサービス」とは一体何か? 偽のVPNソリューションとは、ユーザーのデータを盗み出したり、本人の知らないうちにオンライン活動を追跡することを主な目的として設計されたプログラムのことです。正直に言えば、VPNサービスが正当なものか偽物かを見極めるのは容易ではあ