質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Amazon EC2

Amazon EC2は“Amazon Elastic Compute Cloud”の略称です。Amazon Web Services(AWS)の一部であり、仮想化されたWebサーバーのコンピュータリソースをレンタルできるサービスです。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

解決済

1回答

1581閲覧

[Rails]ブラウザからEC2にアクセスしたときだけMySQLが"...socket '/tmp/mysql.sock' (2)"エラーになるのを解決したい

hajsu00

総合スコア151

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Amazon EC2

Amazon EC2は“Amazon Elastic Compute Cloud”の略称です。Amazon Web Services(AWS)の一部であり、仮想化されたWebサーバーのコンピュータリソースをレンタルできるサービスです。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

1クリップ

投稿2022/05/04 04:43

編集2022/05/05 06:20

AWS初心者です。
RailsアプリをEC2にデプロイしたいのですが、ブラウザでEC2のIPアドレスにアクセスするとMySQLへの接続エラーが発生して解決できずに困っています。

ご助言をいただけると幸いです。

起きている問題

・ブラウザからEC2のIPアドレスにアクセスすると
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
が発生する。
※SSHで直接EC2に入ると、Rails<=>MySQLは正常に動作する(詳細は後述)

前提事項

開発環境

・macOS Monterey v12.1
・ruby v3.0.3
・Rails v6.1.4.4
・MySQL 8.0.28
・puma 5.5.2
・nginx 1.20.0

インフラ構成図

イメージ説明

ディレクトリ構造

directory

1my-app 2├── src 3│ ├── app 4│ ├── bin 5│ ├── config 6│ ├── ... 7│ └── ... 8├── .gitattributes 9├── .gitignore 10└── README.md

関係するコード

EC2内でnginxとpumaを起動済み(設定は以下の通り)

# /etc/nginx/conf.d/my_app.conf upstream puma { server unix:/var/www/my_app/src/tmp/sockets/puma.sock; } server { listen 80; server_name ***.***.***.***; keepalive_timeout 0; access_log /var/log/nginx/my_app.access.log main; client_max_body_size 4G; root /var/www/my_app/src/public; location ~ .*\.(swf|SWF|ico|ICO|jar|txt|gz|js) { root /var/www/my_app/src/public; expires 15m; break; } location ~ ^\/fonts\/* { root /var/www/my_app/src/public; expires 15m; break; } location ~ ^\/assets\/* { root /var/www/my_app/src/public; break; } location ~ ^\/favicon\/* { root /var/www/my_app/src/public; break; } location = /manifest.json { root /var/www/my_app/src/public; break; } location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; #auth_basic "Restricted"; #auth_basic_user_file /etc/nginx/.htpasswd; #if ($http_x_forwarded_proto = "http") { #rewrite ^(.*) https://$server_name$1 #break; #} proxy_pass http://puma; } }

ruby

1# /var/www/my_app/src/config/puma.rb 2 3workers Integer(ENV['WEB_CONCURRENCY'] || 2) 4max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 5min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } 6threads min_threads_count, max_threads_count 7 8preload_app! 9rackup DefaultRackup 10# rails_env = ENV.fetch("RAILS_ENV") { "development" } 11rails_env = "production" 12environment rails_env 13bind "unix:///var/www/my_app/src/tmp/sockets/puma.sock" 14 15pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } 16plugin :tmp_restart 17 18on_worker_boot do 19 # Worker specific setup for Rails 4.1+ 20 # See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot 21 ActiveRecord::Base.establish_connection 22end

yml

1# /var/www/my_app/src/config/database.yml 2 3default: &default 4 adapter: mysql2 5 encoding: utf8mb4 6 reconnect: false 7 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 8 username: root 9 password: <%= ENV['DATABASE_PASSWORD'] %> 10 host: localhost 11 12development: 13 <<: *default 14 database: my_app_development 15 socket: /tmp/mysql.sock 16test: 17 <<: *default 18 database: my_app_test 19 socket: /tmp/mysql.sock 20production: 21 database: my_app_production 22 adapter: mysql2 23 encoding: utf8mb4 24 charset: utf8mb4 25 collation: utf8mb4_general_ci 26 username: <%= Rails.application.credentials.db[:user_name] %> 27 password: <%= Rails.application.credentials.db[:password] %> 28 host: <%= Rails.application.credentials.db[:endpoint] %> 29 pool: 20 30 timeout: 1000 31 socket: /tmp/mysql.sock

試したこと

rails c内ではEC2<=>RDSの通信に成功していることを確認

bash

1[ec2-user@ip-10-0-1-40 src]$ RAILS_ENV=production rails c 2Loading production environment (Rails 6.1.4.4) 3irb(main):001:0> User.count 4=> 0

・EC2内のmysql.sockの場所を調べてdatabase.ymlに記載

console

1[hajsu00@ip-10-0-1-40 conf.d]$ mysql_config --socket 2/var/lib/mysql/mysql.sock

yml

1# /var/www/my_app/src/config/database.yml 2 3default: &default 4 adapter: mysql2 5 encoding: utf8mb4 6 reconnect: false 7 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 8 username: root 9 password: <%= ENV['DATABASE_PASSWORD'] %> 10 host: localhost 11 12development: 13 <<: *default 14 database: my_app_development 15 socket: /tmp/mysql.sock 16test: 17 <<: *default 18 database: my_app_test 19 socket: /tmp/mysql.sock 20production: 21 database: my_app_production 22 adapter: mysql2 23 encoding: utf8mb4 24 charset: utf8mb4 25 collation: utf8mb4_general_ci 26 username: <%= Rails.application.credentials.db[:user_name] %> 27 password: <%= Rails.application.credentials.db[:password] %> 28 host: <%= Rails.application.credentials.db[:endpoint] %> 29 pool: 20 30 timeout: 1000 31 # socket: /tmp/mysql.sock 32 socket: /var/lib/mysql/mysql.sock

→エラー文はCan't connect to local MySQL server through socket '/tmp/mysql.sock' (2)で変化なし

考えたこと

ec2内でのRails<=>MySQL通信には成功していること、ブラウザからhttpアクセスには成功している(Railsのエラー場面が表示されている)ことからnginx<=>pumaで問題が発生していると考えています。
しかし、検索しても長時間解決に至りません。

お手数お掛けしますが、ご助言いただけると幸いです。
よろしくお願いします。

追記(5/5)

68user さんのコメントをもとに検証を進めました。

puma.rbを修正

そもそもpuma.rbが間違いだらけでしたので、書き直しました。

まず、上記実行にあたりサーバー内のRails実行環境を改めて指定。
$ export RAILS_ENV=production

次に、puma.rbを以下のように書き換える。

ruby

1workers Integer(ENV['WEB_CONCURRENCY'] || 2) 2max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } 3min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } 4threads min_threads_count, max_threads_count 5 6preload_app! 7rails_env = ENV.fetch("RAILS_ENV") { "development" } 8environment rails_env 9case rails_env 10 when "development" 11 port ENV.fetch("PORT") { 3000 } 12 when "production" 13 bind "unix:///var/www/hangartalk/src/tmp/sockets/puma.sock" 14end 15 16pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" } 17plugin :tmp_restart 18 19on_worker_boot do 20 # Worker specific setup for Rails 4.1+ 21 # See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot 22 ActiveRecord::Base.establish_connection 23end

その結果、おそらくnginxへ接続できていない

$ curl http://localhost | head % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0

EC2内のRails<=>MySQLは失敗していた

database.ymlの設定を以下の2通りで試しました。

yml

1production: 2 ... 3 # socket: /tmp/mysql.sock 4 port: 3306

それぞれの場合でEC2内でmysql -u {ユーザー名} -pでログインを試みたところ、表題と同じエラーが出ました。
EC2内でもデータベースへの接続に失敗していたことになります。

EC2 => RDS(MySQL)は成功

EC2内からRDSにエンドポイントを指定してログインを試みたところ、成功しました。
ということは、Rails => RDSが失敗している?

bash

1$ mysql -u <ユーザー名> -p -h <RDSのエンドポイント> 2Enter password: 3Welcome to the MariaDB monitor. Commands end with ; or \g. 4Your MySQL connection id is 23 5Server version: 8.0.28 Source distribution 6 7Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. 8 9Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. 10 11MySQL [(none)]> SHOW DATABASES; 12+-----------------------+ 13| Database | 14+-----------------------+ 15| myapp_production | 16| information_schema | 17| mysql | 18| performance_schema | 19| sys | 20+-----------------------+ 215 rows in set (0.00 sec)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

68user

2022/05/04 08:08 編集

その環境は production なわけですよね。 Rails で /tmp/mysql.sock 経由で RDS につながっていると判断しているんですよね (ほんとに成功しているのかな? と思いますが Rails よくわからず)。 RDS に接続するには当然 TCP/IP 経由でつながないといけないわけですが、EC2 内に UNIX ドメインソケットである /tmp/mysql.sock を listen し、RDS に中継してくれる proxy がいるってことですか? RDS Proxy とか使っているってことでしょうか? proxy なんていないということであれば、RDS のポート 3306 につなぐように設定し、セキュリティグループで EC2 から RDS に接続を許可する、というのが一般的かと思います。 とりあえず接続試験は mysql コマンドでやってみた方がよいと思います。
hajsu00

2022/05/05 04:00

お返事遅くなり申し訳ありません。 コメントありがとうございます。 まだ検証が終わっていないのですが、現状を本文に追記させていただきました。 まず、実行環境は production であることを再確認しました。 proxyは設置していないので、ご指摘の通りdatabase.ymlのproductionにport: 3306を記載して検証中です。 またpumaの設定が間違っていたのですが、本文中に追記させたいただいた通り、puma.rbの bind "unix:///var/www/hangartalk/src/tmp/sockets/puma.sock" が実行されているため、pumaはmy_app.conf(nginx)の server unix:/var/www/my_app/src/tmp/sockets/puma.sock; をlistenできていると思われますが、nginxに接続失敗しているので調べています。 (参考サイトによる「unix:///」と「unix:/」との使い分けの意味が未だわからず...)
68user

2022/05/05 09:03 編集

rails や puma はわからないのでこれ以上はお役に立てないようですが、全体的に確認方法が甘い気はします。ps でプロセス見てみるとか、lsof や netstat -a で、ポート80 や UNIXドメインソケットを LISTEN しているのかとか、telnet 等で puma に直接接続できるのかとか、curl を使うにしても結果がよくわからんです (接続失敗なのか、それ以外なのか)。あとログファイルになにか出てないでしょうか? 他の方からの回答がないようなら情報追加して別質問を立ててみてはと思います。
hajsu00

2022/05/05 11:22

ありがとうございます。 質問投稿時より状況が変わってきていますので、別質問を立てたいと思います。 ご指摘いただいた確認方法も、ひとつづつ調べていきたいと思います。 ありがとうございました!
yu_1985

2022/05/06 05:20

ローカルファイルの/tmp/mysql.sockをdefaultに含めてしまうとすべての設定でそれを参照してしまうので、defaultではなく必要な環境にだけ個別に設定すべきではないでしょうか。 接続先がRDSならローカルのソケットファイルを参照してしまうとおかしなことになる気がします。
guest

回答1

0

自己解決

ひとまず、Rails=>RDS(MySQL)への接続は成功したと思いますので、現在の設定を書いていきます。

解決したこと

EC2 => RDSへの接続

bash

1$ mysql -u <ユーザーID> -p -h <RDSのエンドポイント> 2Enter password: ******* 3 4Welcome to the MariaDB monitor. Commands end with ; or \g. 5Your MySQL connection id is 30 6Server version: 8.0.28 Source distribution 7 8Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. 9 10Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. 11 12MySQL [(none)]>

ただ、わざわざRDSのエンドポイントを設定することは絶対必要なのか、よくわかっていません。

Rails => RDS(MySQL)の接続に成功?(rails db:createに成功済)

database.ymlとセキュリティグループの設定変更で、表題のソケットエラーは解消しました。

yml

1# database.yml 2 3default: &default 4 adapter: mysql2 5 encoding: utf8mb4 6 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> 7 username: root 8 password: <%= ENV['DATABASE_PASSWORD'] %> 9 host: localhost 10 socket: /tmp/mysql.sock 11 12development: 13 <<: *default 14 database: my_app_development 15test: 16 <<: *default 17 database: my_app_test 18production: 19 <<: *default 20 database: my_app_production 21 username: <%= Rails.application.credentials.db[:user_name] %> 22 password: <%= Rails.application.credentials.db[:password] %> 23 host: <%= Rails.application.credentials.db[:endpoint] %>

RDSのセキュリティグループを以下のサイトを参考に修正。

https://photo-tea.com/p/aws-ec2-to-rds-connection/

bash

1$ rails db:drop DISABLE_DATABASE_ENVIRONMENT_CHECK=1 2Dropped database 'my_app_production' 3 4$ rails db:create 5Created database 'my_app_production' 6 7$ rails db:migrate 8== 20210217091829 CreateAircraftTypes: migrating ============================== 9-- create_table(:aircraft_types) 10 -> 0.0291s 11== 20210217091829 CreateAircraftTypes: migrated (0.0292s) =====================

railsコマンドでデータベースの操作ができたので、接続はうまくいっているはず。
正しい確認方法を知っている方がいれば教えていただけると幸いです。

新たに発生した問題

Nginx => Pumaの接続に失敗しています。
質問を投稿した頃に表示されていたrailsのエラー画面が表示されなくなってしまったため、調査中です。
これに関しては別質問を投稿予定です。

投稿2022/05/05 11:45

編集2022/05/05 11:51
hajsu00

総合スコア151

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問