connect() to unix:///app/tmp/sockets/puma.sock failed (2: No such file or directory)を解決したい
解決したいこと
ECS Fargateを用いてRails + Nginxで構成したアプリをデプロイしています。
しかしNginxがpuma.sockを参照できず困っています。
発生している問題・エラー
デプロイした時の、NginxコンテナのCloudWatchログ
connect() to unix:///app/tmp/sockets/puma.sock failed
(2: No such file or directory) while connecting to upstream,
client: 10.0.15.207, server: ALBエンドポイント, request: "GET / HTTP/1.1",
upstream: "http://unix:///app/tmp/sockets/puma.sock:/", host: "10.0.18.246"
Nginxログ全体
[notice] 1#1: using the "epoll" event method
[notice] 1#1: nginx/1.25.0
[notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
[notice] 1#1: OS: Linux 5.10.179-166.674.amzn2.x86_64
[notice] 1#1: getrlimit(RLIMIT_NOFILE): 65535:65535
[notice] 1#1: start worker processes
[notice] 1#1: start worker process 7
2023-06-04T10:05:16.747+09:00
2023/06/04 01:05:16 [crit] 7#7: *2 connect() to unix:///app/tmp/sockets/puma.sock failed (2: No such file or directory) while connecting to upstream, client: 10.0.26.206, server: to-do-app-prod-557176862.ap-northeast-1.elb.amazonaws.com, request: "GET / HTTP/1.1", upstream: "http://unix:///app/tmp/sockets/puma.sock:/", host: "10.0.12.172"
2023/06/04 01:05:16 [crit] 7#7: *2 connect() to unix:///app/tmp/sockets/puma.sock failed (2: No such file or directory) while connecting to upstream, client: 10.0.26.206, server: to-do-app-prod-557176862.ap-northeast-1.elb.amazonaws.com, request: "GET / HTTP/1.1", upstream: "http://unix:///app/tmp/sockets/puma.sock:/", host: "10.0.12.172"
また、問題なのかわからないのですがRailsコンテナのログをみると起動時にunix:///app/tmp/sockets/puma.sock
という記述がありませんでした。
こちらの記事を見ると、unix:///app/tmp/sockets/puma.sock
とログが出てるので、Railsコンテナで指定のファイルパスでpumaが動作していないことが原因でしょうか?
該当するソースコード
..
..
pid /var/run/nginx.pid;
http {
upstream app {
# ソケット通信したいのでpuma.sockを指定
server unix:///app/tmp/sockets/puma.sock;
}
include /etc/nginx/conf.d/*.conf;
..
..
}
server {
listen 80 default_server;
server_name ALBエンドポイント;
root /app/public;
location / {
proxy_pass http://app;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count
worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
environment ENV.fetch("RAILS_ENV") { "development" }
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
plugin :tmp_restart
app_root = File.expand_path('..', __dir__)
bind "unix://#{app_root}/tmp/sockets/puma.sock"
FROM ruby:3.2.1 AS base
WORKDIR /app
ENV RAILS_ENV production
ENV NODE_MAJOR_VERSION 14
ENV BUNDLE_PATH vendor/bundle
ENV BUNDLE_WITHOUT development:test
RUN gem update --system && gem install bundler:2.4.8
RUN mkdir -p tmp/pids
RUN mkdir -p tmp/sockets
#builder
FROM base AS builder
RUN curl -sL https://deb.nodesource.com/setup_$NODE_MAJOR_VERSION.x | bash - && \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo 'deb http://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list && \
apt-get update -qq && \
apt-get install -y --no-install-recommends \
vim locales build-essential curl libpq-dev libmariadb-dev nodejs yarn nginx sudo
#bundle
FROM builder AS bundle
COPY Gemfile Gemfile.lock ./
RUN bundle install --jobs=4 --retry=3 && rm -rf $BUNDLE_PATH/ruby/3.2.1/cache/*
#yarn
FROM builder AS yarn
COPY package.json yarn.lock ./
RUN yarn install --production --frozen-lockfile && yarn cache clean
#main
FROM builder AS main
COPY . /app
COPY --from=bundle /app/vendor/bundle /app/vendor/bundle
COPY --from=yarn /app/node_modules /app/node_modules
RUN --mount=type=secret,id=master_key,target=config/master.key,required=true bundle exec rails webpacker:install
RUN NODE_ENV=production ./bin/webpack
COPY docker/production/entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
VOLUME ["/app/public"]
VOLUME ["/app/tmp"]
CMD bash -c "rm -f tmp/pids/server.pid && bundle exec puma -C config/puma.rb"
FROM nginx:1.25
RUN rm -f /etc/nginx/conf.d/* /etc/nginx/nginx.conf
ADD ./nginx/nginx.conf /etc/nginx/nginx.conf
ADD ./nginx/default.conf /etc/nginx/conf.d/default.conf
CMD ["/usr/sbin/nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]
#!/bin/bash
set -e
rm -f /app/tmp/pids/server.pid
RAILS_ENV=production bin/rails db:create
RAILS_ENV=production bin/rails db:migrate
exec "$@"
ECS Fargate
task_definition.json
こちらのドキュメントを参考にバインドマウントを実装しました。
{
"family": "to_do_app-prod",
"containerDefinitions": [
{
"name": "to_do_app-prod",
"image": "943726312182.dkr.ecr.ap-northeast-1.amazonaws.com/to_do_app-prod:latest",
"cpu": 0,
"portMappings": [
{
"name": "to_do_app-prod-3000-tcp",
"containerPort": 3000,
"hostPort": 3000,
"protocol": "tcp",
"appProtocol": "http"
}
],
"essential": true,
"environment": [
{
"name": "RAILS_ENV",
"value": "production"
},
{
"name": "RAILS_MASTER_KEY",
"value": "b30430bbe41e498a955b3900833032e9"
},
{
"name": "DB_USERNAME",
"value": "admin"
},
{
"name": "DB_HOST",
"value": "to-do-app-database-1.chfsoner1ldd.ap-northeast-1.rds.amazonaws.com"
},
{
"name": "DB_PASSWORD",
"value": "30113011tr"
}
],
"mountPoints": [
{
"sourceVolume": "public",
"containerPath": "/app/public",
"readOnly": false
},
{
"sourceVolume": "tmp",
"containerPath": "/app/tmp",
"readOnly": false
}
],
"volumesFrom": [],
"dependsOn": [
{
"containerName": "to_do_app-nginx",
"condition": "START"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-create-group": "true",
"awslogs-group": "/ecs/to_do_app-prod",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs"
}
}
},
{
"name": "to_do_app-nginx",
"image": "943726312182.dkr.ecr.ap-northeast-1.amazonaws.com/to_do_app-nginx:latest",
"cpu": 0,
"portMappings": [
{
"name": "to_do_app-nginx-80-tcp",
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp",
"appProtocol": "http"
}
],
"essential": true,
"environment": [],
"mountPoints": [
{
"sourceVolume": "public",
"containerPath": "/app/public",
"readOnly": false
},
{
"sourceVolume": "tmp",
"containerPath": "/app/tmp",
"readOnly": false
}
],
"volumesFrom": [],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-create-group": "true",
"awslogs-group": "/ecs/to_do_app-prod",
"awslogs-region": "ap-northeast-1",
"awslogs-stream-prefix": "ecs"
}
}
}
],
"executionRoleArn": "arn:aws:iam::943726312182:role/ecsTaskExecutionRole",
"networkMode": "awsvpc",
"volumes": [
{
"name": "public",
"host": {}
},
{
"name": "tmp",
"host": {}
}
],
"requiresCompatibilities": [
"FARGATE"
],
"cpu": "1024",
"memory": "3072",
"ephemeralStorage": {
"sizeInGiB": 21
},
"runtimePlatform": {
"cpuArchitecture": "X86_64",
"operatingSystemFamily": "LINUX"
}
}
コンソール画面
Nginxコンテナ
ボリュームの設定をしているはずなのにボリュームソースが無い?
ドキュメントによるとソースコンテナの指定は以下のようにすればいいとのことでしたが、EC2の場合のみでFargateでは出来ないみたいでした...
"volumesFrom": [
{
"sourceContainer": "web"
}
自分で試したこと
- task_definition.jsonでsource_pathを追加してみましたが、Fargateではサポートしていないとエラーが出ました。
"volumes": [
{
"name": "public",
"host": {
"sourcePath": "/app/public"
}
},
{
"name": "tmp",
"host": {
"sourcePath": "/app/tmp"
}
}
]
Fargate compatible task definitions do not support sourcePath
- nginx.confのupstreamで、直接Railsコンテナを参照するようにしてみました。
upstream app {
server to_do_app-prod:3000; #Railsコンテナ名:Railsコンテナポート番号
}
upstream app {
server to_do_app-prod-3000-tcp:3000; #Railコンテナポート名:Railsコンテナポート番号
}
エラー
nginx: [emerg] host not found in upstream "to_do_app-prod:3000" in /etc/nginx/nginx.conf:20
nginx: [emerg] host not found in upstream "to_do_app-prod-3000-tcp:3000" in /etc/nginx/nginx.conf:20
- nginx.confのlocationを変更しましたがエラー内容に変化はありませんでした。
location / {
try_files $uri $uri/index.html $uri.html @puma;
}
location @puma {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://app;
}
- puma.socketのパスを変更しましたが変化はありませんでした。
upstream app {
server unix:///usr/src/app/tmp/sockets/puma.sock;
}
最後に
馬鹿な話ですがこの作業だけで4日も停滞しています。以下の参考サイトを見ながらやっているのですが解決の兆しが見えません...。そもそも上記のやり方は、Fargateでサポートされていないのでしょうか?
それともどこか間違いがあるのでしょうか?わかる方がいらっしゃいましたらご教授していただきたいです。よろしくお願いします。
参考
FargateにRailsをデプロイする (CI/CDまでの道⑦)
AWS FargateにRailsアプリケーションをデプロイする手順
【ポートフォリオをECSで!】Rails×NginxアプリをFargateにデプロイするまでを丁寧に説明してみた(VPC作成〜CircleCIによる自動デプロイまで) 前編
AWS CDKでRailsアプリをECS(on Fargate)にデプロイしてみる