AWSインフラ構築時のエラー対処備忘録

AWSインフラ構築時のエラー対処備忘録

ECSコンテナサービスを作成中、バックエンド（Rails、Nginx）のサービス作成時に発生したエラーについて記録します。具体的には、NginxのCloudWatchログに以下のエラーが発生しました。

```
connect() to unix:///app/tmp/sockets/puma.sock failed (111: Connection refused) while connecting to upstream, client: 10.0.3.73, server: localhost, request: "GET /api/v1/health_check HTTP/1.1", upstream: "http://unix:///app/tmp/sockets/puma.sock:/api/v1/health_check", host: "10.0.4.4"
```

使用技術

・フロントエンド
　　UIフレームワーク：Nuxt.js(Vue.js), Vuetify
　　HTTP通信：axios
　　コード整形：ESLint/Prettier
・バックエンド
　　言語・フレームワーク：Ruby 3.1.3・Rails 7.0.4
　　コード品質：RuboCop
　　テスト：RSpec
　　サーバー：Nginx, Puma
　　データベース：MySQL 8.0.31
・インフラ/デプロイメント
　　コンテナ：Docker
　　クラウド：AWS (ECR,ECS,Fargate,VPC,S3,Route53,ALB,RDS,ACM,SSM,CloudWatch)
　　IaC(インフラコード化) ：Terraform
　　CI/CD ：GitHub Actions



調査1: NginxとPuma間の通信確認
NginxとPuma間の通信に問題がないか確認するために、まずDocker Composeでコンテナを立ち上げ、その後コンテナ内でソケットファイルの存在やパーミッションを確認しました。

nginxコンテナにアクセス

```
docker exec -it english_app2-web-1 /bin/sh

/ # ls -al /app/tmp/sockets
total 8
drwxr-xr-x  2 root   root     4096 Feb 10 03:28 .
drwxr-xr-x  7 root   root     4096 Dec 5 00:59 ..
srwxrwxrwx  1 root   root       0 Feb 10 03:28 puma.sock
```
rails側のコンテナにもアクセス

```
docker exec -it english_app2-api-1 /bin/sh
/app # ls -al /app/tmp/sockets
total 8
drwxr-xr-x  2 root   root     4096 Feb 10 12:28 .
drwxr-xr-x  7 root   root     4096 Dec 5 09:59 ..
srwxrwxrwx  1 root   root       0 Feb 10 12:28 puma.sock
```

結果、puma.sock が nginx コンテナと Rails アプリケーションが動作している api コンテナの両方に存在し、それぞれのコンテナで同じパス /app/tmp/sockets にあることが確認できました。次に、ECS ExecでECS起動コンテナにアクセスしました。
以下コマンドでNginxコンテナにアクセスし、

```
aws ecs execute-command \
 --region ap-northeast-1 \
 --cluster myapp-prod-ecs-cluster \
 --task b2e9b10e392b4094956a17071fa9d1da \
 --container myapp-prod-container-nginx \
 --command "/bin/sh" \
 --interactive
```
ソケットファイルの存在とパーミッション確認:

```
コマンド
ls -lah /app/tmp/sockets/
実行結果
/ # ls -lah /app/tmp/sockets/
total 8K   
drwxr-xr-x  2 root   root    4.0K Feb 11 10:53 .
drwxr-xr-x  7 root   root    4.0K Feb 11 10:52 ..
srwxrwxrwx  1 root   root      0 Feb 11 10:53 puma.sock
```
Nginxの設定ファイル検証:

```
コマンド
nginx -t
実行結果
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```
Nginxのプロセス状態確認:

```
コマンド
ps aux | grep nginx
実行結果
/ # ps aux | grep nginx
  1 root   0:00 nginx: master process nginx -g daemon off;
  31 root   0:00 nginx: worker process
  32 root   0:00 nginx: worker process
  75 root   0:00 grep nginx
```

次に以下コマンドでrails側のコンテナにもアクセスし、

```
aws ecs execute-command \
 --region ap-northeast-1 \
 --cluster myapp-prod-ecs-cluster \
 --task b2e9b10e392b4094956a17071fa9d1da \
 --container myapp-prod-container-back \
 --command "/bin/sh" \
 --interactive
```

Pumaのプロセス状態確認:

```
コマンド
ps aux | grep puma
実行結果
root     1 0.1 15.4 242576 146992 ?    Ssl 19:52  0:04 puma 5.6.5 (unix:///app/tmp/sockets/puma.soc
root    102 0.0 0.0  1608  764 pts/0  S+  20:30  0:00 grep puma
```
ソケットファイルの存在とパーミッション確認:



```
コマンド
/app # ls -lah /app/tmp/sockets/
実行結果
total 8K   
drwxr-xr-x  2 root   root    4.0K Feb 11 19:53 .
drwxr-xr-x  7 root   root    4.0K Feb 11 19:52 ..
srwxrwxrwx  1 root   root      0 Feb 11 19:53 puma.sock
```
PumaとNginxの設定に問題はなく、両者間の接続も正常であることが確認できました。


調査2: コンテナ起動順序の確認
次に、RailsコンテナとNginxコンテナの起動順序に問題があるのではないかと考えました。Rails側（Puma）が先に起動する必要があるため、タスク定義でNginxコンテナのスタートアップの依存関係の順序に条件「START」を設定し、サービスを更新しました。しかし、エラーは解消しませんでした。
```
            "dependsOn": [
                {
                    "containerName": "myapp-prod-container-back",
                    "condition": "START"
                }
```

恐らくpumaが完全に起動する前にnginx側のコンテナが起動してしまっていることが原因と考えました。下記の記事等を参考にして、Rails側のコンテナにpumaのヘルスチェックを追加した上で、nginx側のdependsOn設定の「“condition”: “START”」の部分を「“condition”: “HEALTHY”」に変更しました。
https://bluepixel.hatenablog.com/entry/2020/04/22/230721

記事を参考にタスク定義の設定を行いましたが、サービス作成時にヘルスステータスが異常となっていました。原因は、curlコマンドがRailsコンテナにインストールされていなかったためでした。RailsコンテナにcurlをインストールするようDockerfileを修正し、ECRにプッシュしてECSサービスを更新したところ、Nginxのログにエラーが表示されなくなり、問題が解決しました。

dockerfileにcurlを追記
```
FROM ruby:3.1.3-alpine

ARG RUNTIME_PACKAGES="linux-headers libxml2-dev make gcc libc-dev nodejs tzdata mysql-dev mysql-client git yarn libc6-compat curl"
以下略
```
・rails側
HealthCheckオプションの設定
```
コマンド CMD-SHELL,curl --unix-socket /app/tmp/sockets/puma.sock http://localhost/api/v1/health_check || exit 1
間隔 30秒
タイムアウト 5秒
開始期間 15秒
再試行 3
```
スタートアップの既存関係の順序
設定なし
・Nginx側
HealthCheckオプションの設定
設定なし

スタートアップの既存関係の順序
条件:Healthy

以上