# ECS + ALB でダウンタイムなしでデプロイ

## ECS + ALB でダウンタイムなしでデプロイ

## Docker

ローカル環境(Mac)には、Docker for Macをインストールして起動しておく。

```
$ vim Dockerfile
```

```dockerfile
FROM ruby:2.3.1

ENV APP_ROOT /usr/src/testapp

WORKDIR $APP_ROOT

RUN apt-get update && \
    apt-get install -y nodejs \
                       --no-install-recommends && \
    rm -rf /var/lib/apt/lists/*

COPY Gemfile $APP_ROOT
COPY Gemfile.lock $APP_ROOT

RUN \
  echo 'gem: --no-document' >> ~/.gemrc && \
  cp ~/.gemrc /etc/gemrc && \
  chmod uog+r /etc/gemrc && \
  bundle config --global jobs 4 && \
  bundle install && \
  rm -rf ~/.gem

COPY . $APP_ROOT

EXPOSE  3000
CMD ["rails", "server", "-b", "0.0.0.0"]
```

```
$ docker build -t ecs-sample/sample .
$ docker run -p 80:3000 ecs-sample/sample
```

<http://localhost> へアクセス

## ECR

```
$ aws ecr get-login --region us-west-2 --profile test
11370* docker login -u AWS -p <発行されるパスワード> -e none https://745403317212.dkr.ecr.us-west-2.amazonaws.com
```

表示される `-e none` は除いて入力。

```
$ docker login -u AWS -p <発行されるパスワード> https://745403317212.dkr.ecr.us-west-2.amazonaws.com
$ docker tag ecs-sample/sample:latest 745403317212.dkr.ecr.us-west-2.amazonaws.com/ecs-test:latest
$ docker push 745403317212.dkr.ecr.us-west-2.amazonaws.com/ecs-test:latest
```

## ECS

* ダウンタイム0のデプロイのために、動的ポートマッピングを設定する。
* 動的ポートマッピングのために、ホストポートを0にする。コンテナポートはアプリケーションのポートに合わせる(Railsでは3000)
* 最小ヘルス率を50へ変更。
* awslogs-groupで指定したCW Groupの値のものを作成してからでないと、ログドライバー: awslogs を設定すると、起動時に以下のエラー。

```
CannotStartContainerError: API error (500): failed to initialize logging driver: ResourceNotFoundException: The specified log group does not exist. status code: 400, request id: 2115d231-14be-11e8-883b-63cc061f87a4 
```

<http://ecs-first-run-alb-1371717613.us-west-2.elb.amazonaws.com/\\>
ALBのエンドポイントでアクセスできるようになる。

## Rails

```
$ vim Gemfile
```

以下はコメントアウト

```
# gem 'coffee-rails', '~> 4.2'
```

```
$ rbenv exec bundle exec rails generate controller sample
$ vim app/controllers/sample_controller.rb
$ vim app/views/sample/index.html.erb
$ vim config/routes.rb
```

具体的な編集内容は以下の通り。

```
require 'socket'

class SampleController < ApplicationController
  def index
    @host = Socket.gethostname
  end
end
```

```
<h1>Host : <%= @host %></h1>
```

Rails.application.routes.draw do \~ end 内に以下を追加。

```
root 'sample#index'
```

## RSpec

```
$ vim Gemfile
```

group :development, :test do \~ end内に以下を追加。

```
gem 'rspec-rails', '~> 3.7.2'
```

```
$ rbenv exec bundle install
$ rbenv exec bundle exec rails generate rspec:install
$ vim .rspec
```

以下を末尾に追記

```
--format documentation
```

```
$ rbenv exec bundle exec rspec
$ vim config/application.rb
```

以下を末尾に追加

```
Rails.application.config.generators do |g|
  g.test_framework :rspec,
    fixtures: true,
    view_specs: false,
    helper_specs: false,
    routing_specs: false,
    controller_specs: true,
    request_specs: false
  g.fixture_replacement :factory_girl, dir: "spec/factories"
end
```

$ vim spec/controllers/sample\_controller\_spec.rb

```
RSpec.describe SampleController, type: :controller do
  describe SampleController do
    context "rspec test" do
      it "test top page 200" do
        get :index
        expect(response).to have_http_status 200
      end$
    end$
  end$
end
```

## Docker Compose

```
$ vim docker-compose.yaml
```

```
version: '3'
services:
  web:
    build: .
    ports:
      - "80:3000"
    command: bundle exec rails server
    volumes:
      - .:/usr/src/testapp
```

```
$ docker-compose build
$ docker-compose up
```

Docker Composeを利用することで、Railsのコードを編集してもビルドし直さないと変更が反映されない事象は解消。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hayashier.gitbook.io/article/aws/ecs-alb-deploy.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
