Docker上にMySQLサーバー構築時につまずいたエラー



<h2>今回の経緯</h2>
Ruby on railsでバッチ処理を行うにあたって、Dockerをインストールしました。
DBはMySQLを使用し、MySQLのデータベースサーバーをDocker上に構築。

問題なく、環境構築を終えローカルPCからDockerのMySQLコンテナへ接続できるようにしました。

環境構築が完了し、いよいよRailsでテーブル作成。
マイグレーションファイルを編集後、データベースに反映させようとしたところ発生したエラーでした。

<h2>環境</h2>

・Mac OS
・Rails 6.0.4.1
・Docker 20.10.8
・mysql2 0.5.3



<h2>エラー内容</h2>

`````````
% bin/rails db:migrate
`````````

を実行したところ、以下のエラーが発生。

``````````
-- Crash Report log information --------------------------------------------
   See Crash Report log file under the one of following:                    
     * ~/Library/Logs/DiagnosticReports                                     
     * /Library/Logs/DiagnosticReports                                      
   for more details.                                                        
Don't forget to include the above Crash Report log file in bug reports.     

〜中略〜

-- Control frame information -----------------------------------------------
c:0042 p:---- s:0236 e:000235 CFUNC  :connect
c:0041 p:0614 s:0224 e:000223 METHOD /Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/mysql2-0.5.3/lib/mysql2/client.rb:90 [FINISH]
c:0040 p:---- s:0210 e:000209 CFUNC  :new

〜中略〜

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: https://www.ruby-lang.org/bugreport.html

[IMPORTANT]
Don't forget to include the Crash Report log file under
DiagnosticReports directory in bug reports.
```````````````````````
原因を調べてみると、MySQLのバージョンが原因なのではないかとのことでした。
その後バージョン変更のためにコマンドを実行するも、他のエラーが発生し、そのために再度別のコマンドを実行しの繰り返しでドツボにハマっていきました。

あれやこれやをやっていた矢先、最終的に以下のxcodeを再インストールを実施して出てしまったエラーに1番苦戦したかたちになってしまいました。

以下の3つのコマンドを実行し、xcodeを再インストールしました。

`````````````
$ sudo rm -rf $(xcode-select -print-path)
$ sudo rm -rf /Library/Developer/CommandLineTools
$ xcode-select --install
``````````````

xcode再インストール完了後、

`````````````
$ yarn install
`````````````



``````````````````````````
1 error generated.
make: *** [Release/obj.target/binding/src/binding.o] Error 1
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/Users/shigatakuma/projects/node_modules/@rails/webpacker/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack     at ChildProcess.emit (node:events:394:28)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
gyp ERR! System Darwin 20.6.0
gyp ERR! command "/usr/local/Cellar/node/16.8.0/bin/node" "/Users/shigatakuma/projects/node_modules/@rails/webpacker/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="
gyp ERR! cwd /Users/shigatakuma/projects/node_modules/@rails/webpacker/node_modules/node-sass
gyp ERR! node -v v16.8.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok 
``````````````````````````
<h2>解決した方法</h2>

以下の3つのコマンドでMySQLの状況を調べます。

```````````
$ brew search mysql
$ which mysql
$ ps aux | grep mysql
```````````
↓実行結果

```````````````
$ brew search mysql

==> Formulae
automysqlbackup            mysql-client@5.7           mysql@5.6 ✔
mysql ✔                    mysql-connector-c++        mysql@5.7
mysql++                    mysql-sandbox              mysqltuner
mysql-client               mysql-search-replace       qt-mysql
==> Casks
homebrew/cask/mysql-connector-python     homebrew/cask/navicat-for-mysql
homebrew/cask/mysql-shell                homebrew/cask/sqlpro-for-mysql
homebrew/cask/mysql-utilities


$ which mysql

/usr/local/bin/mysql


$ ps aux | grep mysql

1685   0.0  0.0  4920184    604   ??  S    20 821    1:24.21 /usr/local/opt/mysql@5.6/bin/mysqld --basedir=/usr/local/opt/mysql@5.6 --datadir=/usr/local/var/mysql --plugin-dir=/usr/local/opt/mysql@5.6/lib/plugin --log-error=shigataumanoAir.err --pid-file=shigataumanoAir.pid
1566   0.0  0.0  4280140      4   ??  S    20 821    0:00.05 /bin/sh /usr/local/opt/mysql@5.6/bin/mysqld_safe --datadir=/usr/local/var/mysql
92976   0.0  0.0  4259000    220 s002  U+    9:50AM   0:00.00 grep mysql
```````````````
以上のコマンドから、
<b>bundle installのときにMySQL5.6の設定を参照してgemがインストールされていることが原因と判明しました。</b>

以下のコマンドでgem mysql2をアンインストールします。

````````````
$ bundle exec gem uninstall mysql2
``````````````
さらにgemをインストールする際の設定を変更します。

``````````````
$ bundle config --local build.mysql2 "--with-mysql-config=/usr/local/bin/mysql_config --with-ldflags=-L/usr/local/opt/openssl@1.1/lib --with-cppflags=-I/usr/local/opt/openssl@1.1/include"
`````````````````
再インストール後、rails db:migrateを実行します。

```````
$ bundle install
$　　bin/rails db:migrate
```````

今度は以下のエラー文が出力されました。

````````````
rails aborted!
Mysql2::Error::ConnectionError: Access denied for user 'batch_user'@'localhost' (using password: YES)
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/mysql2-0.5.3/lib/mysql2/client.rb:90:in `connect'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/mysql2-0.5.3/lib/mysql2/client.rb:90:in `initialize'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/connection_adapters/mysql2_adapter.rb:24:in `new'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/connection_adapters/mysql2_adapter.rb:24:in `mysql2_connection'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:887:in `new_connection'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:931:in `checkout_new_connection'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:910:in `try_to_checkout_new_connection'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:871:in `acquire_connection'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:593:in `checkout'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:437:in `connection'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:1125:in `retrieve_connection'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/connection_handling.rb:221:in `retrieve_connection'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/connection_handling.rb:189:in `connection'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/tasks/database_tasks.rb:238:in `migrate'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/railties/databases.rake:86:in `block (3 levels) in <main>'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/railties/databases.rake:84:in `each'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/activerecord-6.0.4.1/lib/active_record/railties/databases.rake:84:in `block (2 levels) in <main>'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/railties-6.0.4.1/lib/rails/commands/rake/rake_command.rb:23:in `block in perform'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/railties-6.0.4.1/lib/rails/commands/rake/rake_command.rb:20:in `perform'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/railties-6.0.4.1/lib/rails/command.rb:48:in `invoke'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/railties-6.0.4.1/lib/rails/commands.rb:18:in `<main>'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `require'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `block in require_with_bootsnap_lfi'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/loaded_features_index.rb:92:in `register'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:22:in `require_with_bootsnap_lfi'
/Users/shigatakuma/projects/.bundle/ruby/2.6.0/gems/bootsnap-1.8.1/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:31:in `require'
bin/rails:4:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
``````````````````

ローカルで起動しているMySQLへの接続が優先されているかもしれないとのこと。
docker-compose.ymlファイル内記載のポートを変更(3306 → 3307)

``````````
version: '3.8'
services:
  mysql:
    image: mysql:8.0
    volumes:
      - ./tmp/mysql:/var/lib/mysql
    ports:
      # - 3306:3306
      - 3307:3306
    environment:
      - MYSQL_ROOT_PASSWORD=batch
      
``````````````
dockerの再起動

``````````````
$ docker-compose down
$ docker-compose up -d
``````````````
ここが重要ですが、<b>MYSQL_PORTを指定してrails db:migrateを実行する必要があります。</b>

``````````````
$  MYSQL_PORT=3307 bin/rails db:migrate
````````````

`````````````
== 20210830030847 CreateUsers: migrating ======================================
-- create_table(:users, {:comment=>"ゲームのユーザー情報を管理するテーブル"})
   -> 0.0742s
== 20210830030847 CreateUsers: migrated (0.0743s) =============================

== 20210830030923 CreateUserScores: migrating =================================
-- create_table(:user_scores, {:comment=>"ユーザーがゲーム内で獲得した点数"})
   -> 0.1328s
== 20210830030923 CreateUserScores: migrated (0.1329s) ========================

== 20210830031004 CreateRanks: migrating ======================================
-- create_table(:ranks, {:comment=>"ゲーム内のランキング情報"})
   -> 0.1475s
== 20210830031004 CreateRanks: migrated (0.1476s) =============================
````````````````

上手くいきました！！