railsにおけるCan’t connect to local MySQL server through socketエラーの対策法

インフラ

railsでCan’t connect to local MySQL server through socket ‘/run/mysqld/mysqld.sock’ (111)エラーが発生し、解決するのに時間を要してしまったため、同じような問題に遭遇した方の手助けになればと思い記事を作成しました。

そもそもの問題について

今回のエラーが発生する場合、railsとmysqlサーバーはsocket通信を行なっています。ソケットについては下記の記事が参考になりました。

Error 403 (Forbidden)|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
403エラーページです。用語の意味を「ざっくりと」理解するためのIT用語辞典です。

ざっくりの理解ですが、railsとmysqlは別サーバーなのでrailsからmysqlに接続するという過程がありますが、その際にrailsがmysqlを参照する手段(ソケットファイル)が必要のようです。

従って、mysql側のサーバーにソケットファイルがないことが問題と考えます。

socketエラーの対策法

mysqlのsocketファイルに接続先を合わせる

まず、mysqlのsocketファイルがどこにあるか確認します。my.cnfというファイルにsocketファイルの場所があるため、まずはdbのシェル内で、my.cnfがある場所を探す。

sh-4.4# mysql --help | grep my.cnf
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf

3つファイルが存在する場所が見つかりましたが、1つ目の中身を見ていきます。

# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/8.0/en/server-configuration-defaults.html
[mysqld]
socket=/var/run/mysqld/mysqld.sock
...
[client]
socket=/var/run/mysqld/mysqld.sock
...

socketは/var/run/mysqld/mysqld.sockにあることがわかります。

railsのconfig.database.ymlにsockファイルの場所を指定します。

# 開発環境に適用する場合
development:
  <<: *default
  database: myapp_development
  socket: /var/run/mysqld/mysqld.sock

通常だと、これで上記のエラーが解決できるみたいですが、自分の場合はさらに、

Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’ (2)となってしまっていました。

エラー文を見る限り、ちゃんとmy.cnfに記載されているsockファイルを参照できており、configファイルはしっかりと読み込めてます。

【今回の問題】database.ymlの環境変数が適切でなかった

今回、production環境にデプロイするにあったりdatabase.ymlのdefaultを変更してしまったのが原因でした。

# 元々の設定
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db

# デプロイのため変更した内容
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= Rails.application.credentials.db[:username] %>
  password: <%= Rails.application.credentials.db[:password] %>

デプロイ時にdefaultの値を変更したことで、エラーが発生してしまったようです。どうやらデータベース接続時に使用する環境変数が違う場合にもCan’t connect to local MySQL server through socket エラーが発生するみたいです。

ユーザー名やパスワードが違うと出てくれれば解決しやすかったのですね…

Can’t connect to local MySQL server through socket エラーの対策まとめ

今回おおもとの原因としては、環境ごとに環境変数を細かく設定しなかったことが原因になります。早く本番環境で確認したかったため、defaultの値を直接いじってしまったことで今回の問題が発生してしまいました。

developの環境はdevelopにproductionの環境はproductionにそれぞれの値を入れておくことで、今回のエラーに限らずバグが減らせるので、ちょっとした確認をする際でも、しっかり環境ごとに分ける意識を高めていこうと思います。

コメント

タイトルとURLをコピーしました