# Elastic Beanstalkでインスタンス入れ替え後にnginxのデフォルトの画面が表示されてしまう問題の対応

## Elastic Beanstalkでインスタンス入れ替え後にnginxのデフォルトの画面が表示されてしまう問題の対応

### 設定内容

基本的には以下の内容を参考に設定していました。ただし、nginxの設定をカスタムするために。`.ebextensions/`以下にnginxの設定ファイルを追加していました。

* [Elastic Beanstalk への Sinatra アプリケーションのデプロイ](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/ruby-sinatra-tutorial.html)
* [\[Procfile\] でアプリケーションプロセスを設定する](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/ruby-platform-procfile.html)

config.ru

```
require './filet'

run Sinatra::Application
```

Nginxの設定は以下`.ebextensions/`以下に`nginx.config`というファイル名

```
files:
   "/opt/elasticbeanstalk/support/conf/webapp_healthd.conf":
     owner: root
     group: root
     mode: "000644"
     content: |
      upstream my_app {
        server unix:///var/run/puma/my_app.sock;
      }

      log_format healthd '$msec"$uri"'
                      '$status"$request_time"$upstream_response_time"'
                      '$http_x_forwarded_for';

      server {
        listen 80;
        server_name _ localhost; # need to listen to localhost for worker tier


        # AppSec
        # Hide server information
        server_tokens off;

        # Add secure header
        add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';
        add_header Content-Security-Policy "default-src 'none'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; font-src 'self';";

        if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
          set $year $1;
          set $month $2;
          set $day $3;
          set $hour $4;
        }

        access_log  /var/log/nginx/access.log  main;
        access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;

        location / {
          proxy_pass http://my_app; # match the name of upstream directive which is defined above
          proxy_set_header Host $host;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
:
      }
 
container_commands:
  99_restart_nginx:
    command: "systemctl restart nginx || systemctl start nginx"
```

Procfile

```
web: bundle exec puma -C /opt/elasticbeanstalk/config/private/pumaconf.rb
```

### 調査内容

まずは、バンドルログのフルログを取得してログの詳細を確認。

* [Elastic Beanstalk 環境の Amazon EC2 インスタンスからのログの表示](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.logging.html)

ログを確認したところ、以下のような内容でした。

* `eb-engine.log`は特に問題なし。
* Nginxもエラーログは特に出ていない。
* `puma/puma.log`も以下の記録のみで特に問題なし。

```
=== puma startup: 2021-11-20 02:11:31 +0000 ===
=== puma startup: 2021-11-20 02:11:31 +0000 ===
[3019] - Worker 1 (pid: 3112) booted, phase: 0
[3019] - Worker 0 (pid: 3110) booted, phase: 0
```

* `messages`も特に問題なし。

```
Nov 17 01:12:07 ip-172-31-13-104 web: [3227] Puma starting in cluster mode...
Nov 17 01:12:07 ip-172-31-13-104 web: [3227] * Version 4.3.8 (ruby 2.7.4-p191), codename: Mysterious Traveller
Nov 17 01:12:07 ip-172-31-13-104 web: [3227] * Min threads: 8, max threads: 32
Nov 17 01:12:07 ip-172-31-13-104 web: [3227] * Environment: production
Nov 17 01:12:07 ip-172-31-13-104 web: [3227] * Process workers: 2
Nov 17 01:12:07 ip-172-31-13-104 web: [3227] * Phased restart available
Nov 17 01:12:07 ip-172-31-13-104 web: [3227] * Listening on unix:///var/run/puma/my_app.sock
Nov 17 01:12:07 ip-172-31-13-104 web: [3227] Use Ctrl-C to stop
```

次に、Systems ManagerのセッションマネージャーでBeanstalk配下のEC2インスタンスにログインして、OS内の調査をしました。プロセス状況を確認したところ、NginxもPumaも正常に動作していました。

* nginx

```
sh-4.2$ ps aux | grep nginx
root      2936  0.0  0.0  39852   968 ?        Ss   02:11   0:00 nginx: master process /usr/sbin/nginx
nginx     2937  0.0  0.1  40320  2908 ?        S    02:11   0:00 nginx: worker process
nginx     2938  0.0  0.1  40320  2908 ?        S    02:11   0:00 nginx: worker process
ssm-user  3537  0.0  0.0 119416   944 pts/0    R+   02:47   0:00 grep nginx
```

* Puma

```
sh-4.2$ ps aux | grep puma
healthd   2787  0.0  1.9 1025400 38956 ?       Ssl  02:11   0:01 puma 5.3.2 (tcp://127.0.0.1:22221) [healthd]
webapp    3019  0.0  1.6 277540 32900 ?        Ss   02:11   0:00 puma 4.3.8 (unix:///var/run/puma/my_app.sock) [current]
webapp    3110  0.0  3.2 1275924 64400 ?       Sl   02:11   0:01 puma: cluster worker 0: 3019 [current]
webapp    3112  0.0  3.2 1275912 64396 ?       Sl   02:11   0:01 puma: cluster worker 1: 3019 [current]
ssm-user  3531  0.0  0.0 119416   980 pts/0    R+   02:46   0:00 grep puma
```

nginxの設定ファイル自体を見返しても特に問題は見当たらないため、nginxで設定ファイルの再読み込みをしたところ、正常にサービスは動作するようになりました。　

```
sh-4.2$ sudo systemctl reload nginx
```

そのため、`.ebextensions/`以下のnginxの設定ファイルの設定を変更しました。`.ebextensions`以下に`nginx.config`というファイルを作成し、`/opt/elasticbeanstalk/support/conf/webapp_healthd.conf`に対してnginxの設定をしていました。それを`.ebextensions/`以下に`nginx/conf.d/00_elastic_beanstalk_proxy.conf`に直接nginxの設定ファイルをそのまま記載する形で対応しました。

```
upstream my_app {
  server unix:///var/run/puma/my_app.sock;
}
 
log_format healthd '$msec"$uri"'
                '$status"$request_time"$upstream_response_time"'
                '$http_x_forwarded_for';
```

また、`.ebextensions/`以下に`nginx/conf.d/elasticbeanstalk/01_elastic_beanstalk_server.conf`に直接nginxの設定ファイルをそのまま記載する形で対応しました。

```
server_name _ localhost; # need to listen to localhost for worker tier


# AppSec
# Hide server information
server_tokens off;

# Add secure header
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';
add_header Content-Security-Policy "default-src 'none'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; font-src 'self';";

if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
  set $year $1;
  set $month $2;
  set $day $3;
  set $hour $4;
}

access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;

location / {
  proxy_pass http://my_app; # match the name of upstream directive which is defined above
  proxy_set_header Host $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

location /assets {
  alias /var/app/current/public/assets;
  gzip_static on;
  gzip on;
  expires max;
  add_header Cache-Control public;
}

location /public {
  alias /var/app/current/public;
  gzip_static on;
  gzip on;
  expires max;
  add_header Cache-Control public;
}
```

上記のようなファイル構成に至った理由は、`/var/proxy/staging/nginx/nginx.conf`を確認したところ、以下のようなファイル構成になっていました。すなわち、`conf.d/`以下の設定ファイルはhttpディレクティブ直下、`conf.d/elasticbeanstalk/`以下の設定ファイルはserverディレクティブ以下の設定と認識されることを確認したことによるものです。

```
#Elastic Beanstalk Nginx Configuration File

user                    nginx;
error_log               /var/log/nginx/error.log warn;
pid                     /var/run/nginx.pid;
worker_processes        auto;
worker_rlimit_nofile    65743;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    include       conf.d/*.conf;

    map $http_upgrade $connection_upgrade {
        default     "upgrade";
    }

    server {
        listen        80 default_server;
        access_log    /var/log/nginx/access.log main;

        client_header_timeout 60;
        client_body_timeout   60;
        keepalive_timeout     60;
        gzip                  off;
        gzip_comp_level       4;
        gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        # Include the Elastic Beanstalk generated locations
        include conf.d/elasticbeanstalk/*.conf;
    }
}
```

ただし、Amazon Linux 2からは`.ebextensions/`以下ではなく、`.platform/`以下に移す必要がありました。

````
- [Elastic Beanstalk Linux アプリケーションを Amazon Linux 2 に移行する](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.migration-al.html )

    ```
    .ebextensions/nginx ディレクトリで提供されるプロキシ設定ファイルは、.platform/nginx プラットフォームのフックディレクトリに移動する必要があります。
    ```

- [Elastic Beanstalk Linux プラットフォームの拡張](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/platforms-linux-extend.html )
````

***

`eb-engine.log`に以下のログが出力されていました。

```
2021/11/20 04:28:08.104913 [INFO] Executing instruction: start proxy with new configuration
2021/11/20 04:28:08.104938 [INFO] Running command /bin/sh -c /usr/sbin/nginx -t -c /var/proxy/staging/nginx/nginx.conf
2021/11/20 04:28:08.113014 [ERROR] An error occurred during execution of command [app-deploy] - [start proxy with new configuration]. Stop running the command. Error: copy proxy conf from staging failed with error validate nginx configuration failed with error Command /bin/sh -c /usr/sbin/nginx -t -c /var/proxy/staging/nginx/nginx.conf failed with error exit status 1. Stderr:nginx: [emerg] duplicate upstream "my_app" in /var/proxy/staging/nginx/conf.d/elasticbeanstalk-nginx-ruby-upstream.conf:1
nginx: configuration file /var/proxy/staging/nginx/nginx.conf test failed
```

そのため、以下の設定を削除しました。

```
upstream my_app {
    server unix:///var/run/puma/my_app.sock;
}
```

すると以下のエラー

```
2021/11/20 04:32:20.810099 [INFO] Executing instruction: start proxy with new configuration
2021/11/20 04:32:20.810124 [INFO] Running command /bin/sh -c /usr/sbin/nginx -t -c /var/proxy/staging/nginx/nginx.conf
2021/11/20 04:32:20.817660 [ERROR] An error occurred during execution of command [app-deploy] - [start proxy with new configuration]. Stop running the command. Error: copy proxy conf from staging failed with error validate nginx configuration failed with error Command /bin/sh -c /usr/sbin/nginx -t -c /var/proxy/staging/nginx/nginx.conf failed with error exit status 1. Stderr:nginx: [emerg] duplicate "log_format" name "healthd" in /var/proxy/staging/nginx/conf.d/healthd_logformat.conf:3
nginx: configuration file /var/proxy/staging/nginx/nginx.conf test failed
```

<https://hayashier.com/article/beanstalk-migrate-alami-alami2/\\>
.exextentions以下ではなく.platform以下に設定ファイルをおいたほうがよい。


---

# 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/beanstalk-sinatra-unexpected-launch.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.
