概要
ruby on railsのDocker開発環境構築中に上記エラーが発生しました。
いくつかの問題が複合していて、解決までにちょっと時間がかかってしまったので、備忘録がてらに記録を残しておいて、後続の誰か参考にしてくれたらな〜という目的でゆるく解決方法を記載しておきます。
解決手順(要約)
① socketファイルがどこにあるか確認してdatabase.ymlに設定する
② database.ymlのhost名を変更する
解決までの道のり
以下のようにdocker-compose.ymlを定義して、rails new ~で各種ファイルを生成し、あとはrake db:createすればサーバー起動できる…というところまで来ていました。(railsのバージョンは7.1.2)
version: '3'
services:
db:
image: mysql:5.7
environment:
MYSQL_USER: ${MYSQL_USER_NAME}
MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD}
TZ: "Asia/Tokyo"
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
tty: true
stdin_open: true
volumes:
mysql_data:
ところが、実際に以下のようにコマンドを実行すると表題のエラーが発生。
docker compose run web bundle exec rake db:create
エラー文から考えて、ソケットファイルが問題になっているようだったので、ソケットファイルがどこにあるのかを以下のコマンドで確認。ついでにmysqlコンテナに入って、ちゃんとmysqlがインストールされてて動作することも確認しました。
$ docker compose run db mysql_config socket
/var/lib/mysql/mysql.sock
$ docker compose exec -it <container_name>
bash-4.2# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.44 MySQL Community Server (GPL)
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
- 今回は、dbコンテナの中にmysql.sockファイルがちゃんと作成されていて、パスも認識されていたので問題ありませんでしたが、
mysql_config socket
コマンドを叩いてファイルが見つからなかった場合は、ファイルを生成してあげる必要があります。
その場合の対応方法は以下の記事などを参考にしてください。
次に、デフォルトで生成されてたdatabase.ymlを見たところ、特にsocketファイルのパス等は指定されていなかったため、以下のように設定を追記をしました。
しかしながら、エラーはCan't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
から変わらず…。
# MySQL. Versions 5.5.8 and up are supported.
#
# Install the MySQL driver
# gem install mysql2
#
# Ensure the MySQL gem is defined in your Gemfile
# gem "mysql2"
#
# And be sure to use new-style password hashing:
# https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html
#
development:
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: ${MYSQL_USER_NAME}
password: ${MYSQL_PASSWORD}
host: localhost
+ socket: /var/lib/mysql/mysql.sock
別の原因があるのではないかということで調査をしていたところ、下記の記事を読んでいる最中に、database.ymlのhostの設定がlocalhostになっていることに気づきました。
# MySQL. Versions 5.5.8 and up are supported.
#
# Install the MySQL driver
# gem install mysql2
#
# Ensure the MySQL gem is defined in your Gemfile
# gem "mysql2"
#
# And be sure to use new-style password hashing:
# https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html
#
development:
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: ${MYSQL_USER_NAME}
password: ${MYSQL_PASSWORD}
- host: localhost
+ host: db
socket: /var/lib/mysql/mysql.sock
hostをmysqlコンテナのサービス名に変えて再度rake db:createを試したところ、無事コマンドが通ってサーバーが起動することが確認できました。
まとめ
原因としては、①ソケットファイルのパスが正しく設定されていなかったことと、②database.ymlのhostの設定がlocalhostになっているせいで、mysqlコンテナが認識されなかったことなのかなと思っていますが、ちゃんと文献をあたった訳ではないので正しい理解かは若干怪しいです。
とりあえずmysqlに接続できない問題は解決はしたので、ヨシということで👉