Dockerを導入したRailsをAWSでデプロイ

#### 接続状態の確認

```
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
6896cfc00d7f        redis               "docker-entrypoint.s…"   2 months ago        Up 4 days           6379/tcp            rails-redis
```

```
$ curl -G 'http://localhost:3000'
curl: (7) Failed to connect to localhost port 3000: 接続を拒否されました
```

```
$ netstat -na | grep -i 3000
```
何も表示されなかった。

- Railsの起動がうまくいっていない。
 - 原因はcredentials周り
 - SECRET_KEY_BASEの環境変数を指定してやれば良い
 - 再発行する必要がある
- 再発行するには
 - Railsが動く環境で、rails secretなどのコマンドで、
 　credential.yml.encなどをセットアップする
 - SECRET_KEY_BASEに指定する値も合わせて取得する
     - Railsが動く環境はEC2でも良い
     - 起動しているコンテナの内部でも良い
     - Mac,Linuxなど任意のOSでも良い

***     
#### 本番環境での秘密鍵の設定

Dockerのコンテナ内で
rails secretを実行する。

```Ruby:Dockerfile
FROM ruby:2.6.6
RUN curl -sL https://deb.nodesource.com/setup_11.x | bash -

COPY ./ /var/www/footomo

WORKDIR /var/www/footomo

COPY Gemfile /var/www/footomo
COPY Gemfile.lock /var/www/footomo

RUN apt-get update
RUN apt-get upgrade -y
RUN gem update bundler 
RUN apt-get install build-essential patch ruby-dev zlib1g-dev liblzma-dev -y
RUN bundle install 
RUN rails secret

ENV RAILS_ENV production

EXPOSE 3000
```

ビルドを実行する。

```
$ docker-compose up -d --build
Building local-rails
Step 1/14 : FROM ruby:2.6.6
 ---> 3b3341750de7
(途中省略)
Step 12/14 : RUN rails secret
 ---> Running in 1a1e8d43ca8c
a3d41e4a4d909b2d7112799a7e0402784cc66104********************90309b97534287994b7f0ab4f3b310e59c8ee77af765b5573
(途中省略)
Successfully built f094f47080e7
Successfully tagged footomo_local-rails:latest
rails-redis is up-to-date
Recreating rails-rails ... done
```

秘密鍵が生成されたので、
env_file.envに追記する。

```ruby:env_file.env
RAILS_DATABASE_PASSWORD="********"
RAILS_DATABASE_HOST=*******.ap-northeast-1.rds.amazonaws.com
RAILS_DATABASE_USER="*****"
REDIS_HOST=rails-redis
REDIS_PORT=6379
SECRET_KEY_BASE=a3d***********573(本当はもっと長いです）
```

```ruby:secret.yml
development:
  secret_key_base: 63a***********a4fc923b6cfe7f

test:
  secret_key_base: 6d0**************15c5ad03c12

production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
```

***

#### 再度、接続を試みる

```
$ curl -G 'http://localhost:3000'
```
```
<!DOCTYPE html>
<html>
  <head>
(省略）
    </div>
  </body>
</html>
```
HTMLが表示された。
Dockerが起動して、Railsが動いている。

***

#### コマンドのおさらい

- curl：シェルコマンドでWebサーバにアクセスして、Webページに関するいろ 
いろな情報やデータを取得できる。シェルは、ユーザが入力したコマンドを解釈してカーネルに処理を依頼し、その結果やメッセージなどを画面に表示する機能を持っている。
- netsat：ホストのネットワーク接続状態やソケット／インターフェイスごとのネットワーク統計などを確認するためのコマンド。
- grep：ファイル中の文字列を検索するコマンド。

****

#### 再び、接続不可

少し触りながら、数日後に接続を試みたが拒否される。

```
$ curl -G 'http://localhost:3000'
curl: (7) Failed to connect to localhost port 3000: 接続を拒否されました
```

再度、ビルドを実行

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

```
Building local-rails
Step 1/13 : FROM ruby:2.6.6
 ---> 3b3341750de7
Step 2/13 : RUN curl -sL https://deb.nodesource.com/setup_11.x | bash -
 ---> Using cache
（省略）
ERROR: Service 'local-rails' failed to build: Error processing tar file(exit status 1): write /usr/local/bundle/gems/libv8-8.4.255.0-x86_64-linux/vendor/v8/include/v8.h: no space left on device
```

ディスクスペースが足りず、エラーが出ている。
追加するか、ファイルなどを消してスペースを増やす必要がある。

Dockerイメージは要領を使う為、
不要なものがあれば削除する。
コンテナも消す必要がある場合もある。

***

#### Dockerコンテナの整理

コンテナの状況を確認する。

```
$ docker ps -a
```

20以上のコンテナが溜まっていた。
ビルドする度に溜まっていくので、
不要なものを削除する。

```
$ docker rm [Container ID]
```

次に、imageも整理する。

```
docker images
```

こちらもかなり多くのimageが溜まっていた為、
不要なものを削除した。

```
docker rmi [Image ID]
```

容量の整理ができた。

***

### ビルドの再実行

```
docker-compose up -d --build
```

```
（省略）
Successfully built d1f696d5e5ca
Successfully tagged footomo_local-rails:latest
rails-redis is up-to-date
Creating rails-rails ... done
```

無事にビルドできた。

ちなみに、Redisとは何か調べてみた。

>redisはシンプルかつ高速なデータベース。
キャッシュ、セッションデータ、大量データ送信データなど、
一時的なデータの保管先として利用できる。
通常は、ブラウザでクッキーに一時データを保管するが、
Redisに保管して、Railsを高速化できる。

***

#### ブラウザにアクセス

```
http://54.248.19.33:3000/
```
にアクセスしてみた。
無事に表示された。

***

#### 接続不可、再び

色々触っていたら、また接続ができなくなった。
__接続状況を確認する。__

まず、コンテナの状況を確認。

```
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ef4890f3f744 footomo_local-rails "bundle exec rails s…" 3 days ago Up 3 days 0.0.0.0:80->3000/tcp rails-rails
73723772ef54 redis "docker-entrypoint.s…" 3 days ago Up 3 days 6379/tcp rails-redis
```

この結果から、ローカルホスト（EC2インスタンス）のポート80と、
Railsコンテナのポート3000がBindされていることがわかる。

Bindとは、接続されているということで、
localhost:80 へアクセスすると、その通信はRailsコンテナの3000に繋がる。

続いて、TCPの通信状態を確認する。

```
$ netstat -na | grep -i 3000
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      
tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN      
tcp        0      0 0.0.0.0:41519               0.0.0.0:*                   LISTEN      
tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LISTEN      
tcp        0      0 :::22                       :::*                        LISTEN      
tcp        0      0 :::111                      :::*                        LISTEN      
tcp        0      0 :::80                       :::*                        LISTEN      
tcp        0      0 :::34641                    :::*                        LISTEN 
```

この時点で、localhost:80へのTCP通信が可能な状態になっている。

このポートに対して、curlでHTTPアクセスしたとき、
HTMLが返ってくれば、Railsが正しく起動できているといえる。

curlを実行する。

```
$ curl -X GET http://localhost:80
<!DOCTYPE html>
<html>
  <head>
（省略）
    </div>
  </body>
</html>

```

HTMLが返ってきた為、
Railsが起動できていることがわかった。

__しかし、まだブラウザへの表示ができない。__

ログをみたいが、それも表示されない。

***

#### ポート接続

接続できなくなってからも、
http://54.248.19.33:3000/　
にアクセスしていた。

しかし、docker-compose.ymlを
以下の様に修正していた。

```ruby:docker-compose.yml
version: "3"

services:
  local-redis:
    image: redis
    container_name:
      rails-redis

  local-rails:
    build: .
    ports:
      # - "3000:3000"
      - "80:3000"
    depends_on:
      - local-redis
    env_file:
      - env_file.env
    container_name:
      rails-rails
    command:
      bundle exec rails s -b 0.0.0.0
      # bundle exec rails s -e production
```

portsのところで、
```- "3000:3000"```を
```- "80:3000"に修正していた。

つまり、自分のパソコンではポート番号８０（HTTP通信）に、
dockerコンテナはポート番号3000(Rails)でバインドしていた。

よって、
http://54.248.19.33
にアクセスすることで、HTMLが表示された。

***

#### ログの表示

env_file.envにRAILS_LOG_TO_STDOUT=1を追記。

```ruby:env_file.env
RAILS_DATABASE_PASSWORD="******"
RAILS_DATABASE_HOST=********.ap-northeast-1.rds.amazonaws.com
RAILS_DATABASE_USER="****"
REDIS_HOST=rails-redis
REDIS_PORT=6379
SECRET_KEY_BASE=ca5*******e5a677d3ae882ab3d
RAILS_LOG_TO_STDOUT=1
```

#### ログの確認

まずは、設定を反映する為にビルド。

```
$ docker-compose build
```

ログの表示を確認する。

```
$ docker-compose up
Starting footomo-redis ... done
Recreating footomo-rails ... done
Attaching to footomo-redis, rails-rails
(省略）
rails-rails    | [22d3bec9-970b-4b93-ba66-33f33d0b5c58] puma (3.12.6) lib/puma/thread_pool.rb:135:in `block in spawn_thread'
```

かなり多くのエラーが出力された。
エラーだけを書き出すとこんな感じ。

```
ActionController::RoutingError (No route matches [GET] "/stylesheets/application.css"):
ActionController::RoutingError (No route matches [GET] "/javascripts/application.js"):
HTTP parse error, malformed request (): #<Puma::HttpParserError: Invalid HTTP format, parsing fails.>
ActionController::RoutingError (No route matches [GET] "/tree"):
ActionController::RoutingError (No route matches [GET] "/manager/html"):
ActionController::RoutingError (No route matches [GET] "/wp-login.php"):
Read error: #<RuntimeError: No REQUEST PATH>
ActionController::RoutingError (No route matches [GET] "/shell"):
HTTP parse error, malformed request (): #<Puma::HttpParserError: Invalid HTTP format, parsing fails.>
```

引き続き、エラーを1つ1つ解決していく。
本記事はここまでです。