##はじめに
Docker×MySQL×RailsAPI×Next.jsでポートフォリオ用の環境構築中に出現したエラー。
一日半みっちり悩んでいろんな方法を試したので、ここに戦いの記録を書き記す。
##環境
Docker:version3
MySQL:8.0
##状況
DockerからRailsのサーバーを立ち上げようとコンテナを起動し、docker-compose run api rails db:create
すると、下記エラーでデータベースが作成されない。
my_app $ docker-compose run api rails db:create
Starting database ... done
Creating unknown_music_api_run ... done
Unknown MySQL server host 'db' (-2)
Couldn't create 'api_development' database. Please check your configuration.
rails aborted!
ActiveRecord::ConnectionNotEstablished: Unknown MySQL server host 'db' (-2)
/app/bin/rails:5:in `<top (required)>'
/app/bin/spring:10:in `block in <top (required)>'
/app/bin/spring:7:in `<top (required)>'
Caused by:
Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (-2)
/app/bin/rails:5:in `<top (required)>'
/app/bin/spring:10:in `block in <top (required)>'
/app/bin/spring:7:in `<top (required)>'
Tasks: TOP => db:create
(See full trace by running task with --trace)
ERROR: 1
unknown_music $ docker-compose build
ERROR: yaml.scanner.ScannerError: mapping values are not allowed here
in "./docker-compose.yml", line 22, column 16
unknown_music $ docker-compose build
ERROR: yaml.scanner.ScannerError: mapping values are not allowed here
in "./docker-compose.yml", line 22, column 18
とりあえずエラー文を検索して上から試すローラー作戦実行。
##ローラー作戦
###1)DockerとMySQLのコネクト確認
どうやらDocker-compose.ymlのserver名とRailsのdatabase.ymlのhost名が同じじゃないと正常に繋がらないみたいなのでそこを確認。
version: "3"
services:
db: #database.ymlのhostと同じにする必要がある
container_name: database
image: mysql:8.0
command: ["--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci", "--default-authentication-plugin=mysql_native_password"]
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: api_development
MYSQL_USER: root
MYSQL_PASSWORD: password
TZ: Asia/Tokyo
ports:
- 3308:3306
volumes:
- ./back/database/my.cnf:/etc/mysql/conf.d/my.cnf
- ./back/database/data:/var/lib/mysql
- ./back/database/sql:/docker-entrypoint-initdb.d
...下記省略
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password: password
host: db #ここをserver名と一致させる。
、、、どうやら問題はないらしい
###2)Dockerイメージ全削除
Dockerの古いイメージが残ってしまい、そちらを参照し続けてしまったことでエラーが起きるのでは?と言う記事を発見し試してみる。
このアプリの構築自体3回目くらい(作っては消してをくりかえした)なのでそれじゃないか!?と思い実行
$ docker stop $(docker ps -q)
$ docker rm $(docker ps -aq)
$ docker rmi $(docker images -q)
した後に
$ docker-compose build # コンテナをビルド
$ docker-compose up # コンテナの一斉起動
からの
$ docker-compose run web rails db:create
が、うまくいかず、、、
###3)Docker-compose.yml編集
これをVolumesに足したら上手く行ったよ!との記事を発見し実行。
volumes:
- ./tmp/db:/var/lib/mysql/data → ここの部分を足す
が、ダメ。
###4)削除系コマンド強化版
溜まっていく不要なコンテナやイメージを全消しする削除コマンドでコンテナを綺麗にしてみる。
docker system prune --force --volumes
が、結果は変わらず。
他にもこまごました変更を試しまくり、一日目終了。
二日目は朝からPC再起動してみたり、Dockerコンテナを削除したり、MySQLを再インストールしたりして、
エラー検索のGoogle画面は、3ページまで踏んだリンクで色が変わり、こりゃいよいよ分からんぞ、、、と諦めムード。
ちょっと昼寝してから、もう脳死エラー文ローラー検索攻撃にたよらずに自分でエラーを理解する決意を固める←遅い
とりあえず問題の切り分けをしてみよう。
###5)MySQLのroot権限のパスワード
問題はDockerなのかMySQLなのか。
コンテナを見てみると、、、
どうやら立ち上がってないらしい。
unknown_music $ docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------
back rails server -b 0.0.0.0 Up 0.0.0.0:3000->3000/tcp
database docker-entrypoint.sh --cha ... Exit 1
web docker-entrypoint.sh yarn dev Up 0.0.0.0:4001->3000/tcp
と言うことは、エラーの原因はMySQLではなくDockerか?と思い、DockerDesktopから該当コンテナのエラーlogを読む。
すると、[ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
と言う所で処理が止まっているではないか!!
これはつまり、MySQLのrootパスワードが設定されてない時に、 MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
をdocker-compose.yml
に記載することでMYSQL_ROOT_PASSWORD
を空白にできると言うもの。
そうかMySQLを最インストールした時にrootのパスワード空にしたな、、、と思い、
このヒントを得て、編集したdocker-compose.yml
がこちら。
version: "3"
services:
db: #database.ymlのhostと同じにする必要がある
container_name: database
image: mysql:8.0
command: ["--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci", "--default-authentication-plugin=mysql_native_password"]
environment:
MYSQL_ROOT_PASSWORD: #ここが空白
MYSQL_DATABASE: api_development
MYSQL_USER: root
MYSQL_PASSWORD: password
MYSQL_ALLOW_EMPTY_PASSWORD: "yes" #これ追加
TZ: Asia/Tokyo
ports:
- 3308:3306
volumes:
- ./back/database/my.cnf:/etc/mysql/conf.d/my.cnf
- ./back/database/data:/var/lib/mysql
- ./back/database/sql:/docker-entrypoint-initdb.d
...以下省略
やっったあああああああああああああああああ
##総括
やっぱり脳死でエラー文検索して上から試すのはあんまり良く無いなと学びました。
便利な世の中で優秀な先人達が書き記した知へ一瞬でアクセスできることで自分で考えることを放棄してはいけないな、と。
やはり自分で考え、問題を切り分け仮説を立て検証し、実行していくと言うプロセスが最も大事なんだと痛感した次第であります。
さあアプリ作ろ。