はじめに
ECS FargateでRailsとNginxをデプロイしています。デプロイしようとすると以下のようなエラーが出ます。
発生している問題・エラーメッセージ
connect() to unix:///app/tmp/sockets/puma.sock failed (2: No such file or directory) while connecting to upstream, client: 10.0.13.107, server: to-do-app-1539298331.ap-northeast-1.elb.amazonaws.com, request: "GET / HTTP/1.1", upstream: "http://unix:///app/tmp/sockets/puma.sock:/", host: "10.0.14.202"
該当のソースコード
Dockerfile
Docker
1FROM ruby:3.2.1 AS base 2 3WORKDIR /app 4ENV RAILS_ENV production 5ENV NODE_MAJOR_VERSION 14 6ENV BUNDLE_DEPLOYMENT true 7ENV BUNDLE_PATH vendor/bundle 8ENV BUNDLE_WITHOUT development:test 9RUN gem update --system && gem install bundler:2.4.8 10 11#builder 12FROM base AS builder 13 14RUN curl -sL https://deb.nodesource.com/setup_$NODE_MAJOR_VERSION.x | bash - && \ 15 curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ 16 echo 'deb http://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list && \ 17 apt-get update -qq && \ 18 apt-get install -y --no-install-recommends \ 19 vim locales build-essential curl libpq-dev libmariadb-dev nodejs yarn nginx sudo 20 21#bundle 22FROM builder AS bundle 23COPY Gemfile Gemfile.lock ./ 24RUN bundle install --jobs=4 --retry=3 && rm -rf $BUNDLE_PATH/ruby/3.2.1/cache/* 25 26#yarn 27FROM builder AS yarn 28COPY package.json yarn.lock ./ 29# --productionはproductionに関係するパッケージ、--frozen-lockfileでバージョンの整合性を保つ 30RUN yarn install --production --frozen-lockfile && yarn cache clean 31 32#main 33FROM builder AS main 34 35COPY . /app 36COPY --from=bundle /app/vendor/bundle /app/vendor/bundle 37COPY --from=yarn /app/node_modules /app/node_modules 38RUN --mount=type=secret,id=master_key,target=config/master.key,required=true bundle exec rails webpacker:install 39RUN NODE_ENV=production ./bin/webpack 40 41COPY docker/production/entrypoint.sh /usr/bin/ 42RUN chmod +x /usr/bin/entrypoint.sh 43ENTRYPOINT ["entrypoint.sh"] 44 45# Nginxから参照できるようにする 46RUN mkdir -p tmp/pids 47RUN mkdir -p tmp/sockets 48VOLUME /app/public 49VOLUME /app/tmp 50 51CMD bash -c "rm -f tmp/pids/server.pid && bundle exec puma -C config/puma.rb"
Dockerfile.nginx
Docker
1FROM nginx:1.25 2 3RUN rm -f /etc/nginx/conf.d/* /etc/nginx/nginx.conf 4ADD ./nginx/nginx.conf /etc/nginx/nginx.conf 5ADD ./nginx/default.conf /etc/nginx/conf.d/default.conf 6CMD ["/usr/sbin/nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]
config/puma.rb
ruby
1max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 2min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } 3threads min_threads_count, max_threads_count 4worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" 5environment ENV.fetch("RAILS_ENV") { "development" } 6pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } 7plugin :tmp_restart 8app_root = File.expand_path('..', __dir__) 9bind "unix://#{app_root}/tmp/sockets/puma.sock"
nginx/nginx.conf
user nginx; worker_processes 1; error_log /var/log/nginx/error.log info; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; upstream app { server unix:///app/tmp/sockets/puma.sock; } include /etc/nginx/conf.d/*.conf; }
nginx/default.conf
server { listen 80 default_server; server_name ALBエンドポイント; access_log /dev/stdout main; #ルートディレクトリ root /app/public; #Nginxへのリクエストをバックエンドに送信 location / { proxy_pass http://app; } }
task_definition.json
json
1{ 2 "family": "to_do_app-prod", 3 "containerDefinitions": [ 4 { 5 "name": "to_do_app-prod", 6 "image": "943726312182.dkr.ecr.ap-northeast-1.amazonaws.com/to_do_app-prod:latest", 7 "cpu": 0, 8 "portMappings": [], 9 "essential": true, 10 "environment": [ 11 { 12 "name": "RAILS_ENV", 13 "value": "production" 14 }, 15 { 16 "name": "RAILS_MASTER_KEY", 17 "value": "b30430bbe41e498a955b3900833032e9" 18 }, 19 { 20 "name": "DB_USERNAME", 21 "value": "admin" 22 }, 23 { 24 "name": "DB_HOST", 25 "value": "to-do-app-database-1.chfsoner1ldd.ap-northeast-1.rds.amazonaws.com" 26 }, 27 { 28 "name": "DB_PASSWORD", 29 "value": "30113011tr" 30 } 31 ], 32 "mountPoints": [ 33 { 34 "sourceVolume": "public", 35 "containerPath": "/app/public", 36 "readOnly": false 37 }, 38 { 39 "sourceVolume": "tmp", 40 "containerPath": "/app/tmp", 41 "readOnly": false 42 } 43 ], 44 "volumesFrom": [], 45 "logConfiguration": { 46 "logDriver": "awslogs", 47 "options": { 48 "awslogs-create-group": "true", 49 "awslogs-group": "/ecs/to_do_app-prod", 50 "awslogs-region": "ap-northeast-1", 51 "awslogs-stream-prefix": "ecs" 52 } 53 } 54 }, 55 { 56 "name": "to_do_app-nginx", 57 "image": "943726312182.dkr.ecr.ap-northeast-1.amazonaws.com/to_do_app-nginx:latest", 58 "cpu": 0, 59 "portMappings": [ 60 { 61 "name": "to_do_app-nginx-80-tcp", 62 "containerPort": 80, 63 "hostPort": 80, 64 "protocol": "tcp", 65 "appProtocol": "http" 66 } 67 ], 68 "essential": true, 69 "environment": [], 70 "mountPoints": [ 71 { 72 "sourceVolume": "public", 73 "containerPath": "/app/public", 74 "readOnly": false 75 }, 76 { 77 "sourceVolume": "tmp", 78 "containerPath": "/app/tmp", 79 "readOnly": false 80 } 81 ], 82 "volumesFrom": [], 83 "logConfiguration": { 84 "logDriver": "awslogs", 85 "options": { 86 "awslogs-create-group": "true", 87 "awslogs-group": "/ecs/to_do_app-prod", 88 "awslogs-region": "ap-northeast-1", 89 "awslogs-stream-prefix": "ecs" 90 } 91 } 92 } 93 ], 94 "executionRoleArn": "arn:aws:iam::943726312182:role/ecsTaskExecutionRole", 95 "networkMode": "awsvpc", 96 "volumes": [ 97 { 98 "name": "public", 99 "host": {} 100 }, 101 { 102 "name": "tmp", 103 "host": {} 104 } 105 ], 106 "requiresCompatibilities": [ 107 "FARGATE" 108 ], 109 "cpu": "1024", 110 "memory": "3072", 111 "runtimePlatform": { 112 "cpuArchitecture": "X86_64", 113 "operatingSystemFamily": "LINUX" 114 } 115}
Cloud WatchのRailsコンテナログ
Listening on unix:////app/tmp/sockets/puma.sock
という表示がないのはpuma.sockを参照してないのかと思い、上記task_definition.jsonでは"portMappings": []
を設定してみたのですが変わりませんでした。
試したこと
- ドキュメントの「Dockerfile 内のパスとその内容をコンテナに公開する」という項目を参照しながら実装しました。
- nginx.confファイルでRailsコンテナに接続するようにしてみましたがダメでした。
nginx.conf
1 upstream app { 2 server to_do_app-prod:3000; #コンテナ名:ポート番号 3 } 4 5 upstream app { 6 server to_do_app-prod-3000-tcp:3000; #ポート名:ポート番号 7 }
ECSコンソールの操作方法が違う
複数のサイトを参考にさせていただいたのですが、当時と今のECSコンソールでの操作方法が違いました。
以下参考サイトのECSコンソール画面
どのサイトでも上記のようなコンソール画面で、「ボリュームソースを設定することでrailsのDockerfileで設定したVolumeの内容を共有することができます」というようなことが書いてありました。
上記の設定が原因でエラーが出てるのかはわかりませんが、一応ドキュメント通りに操作しました。
Rails + Nginx + ECS Fargateの情報が少なく、出てきた情報を参考に実装しても上手くいかず困ってます。どのようにすれば良いのでしょうか?
参考にしたサイト
FargateにRailsをデプロイする (CI/CDまでの道⑦)
AWS FargateにRailsアプリケーションをデプロイする手順
【ポートフォリオをECSで!】Rails×NginxアプリをFargateにデプロイするまでを丁寧に説明してみた(VPC作成〜CircleCIによる自動デプロイまで) 前編
補足情報(FW/ツールのバージョンなど)
Ruby 3.2.1
Rails 6.1.7.3
Docker version 23.0.5
Amazon ECS Fargate
Nginx 1.25
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/06/07 02:59