エラー内容
Can't connect to MySQL server on 'db'と表示され
dbコンテナが完全に起動する前にbackendコンテナが動作している。
user@usernoMacBook-Air backend% docker-compose up
[+] Running 3/2
✔ Network backend_default Created 0.0s
✔ Container db Created 0.0s
✔ Container backend Created 0.0s
Attaching to backend, db
db | 2024-01-13 14:39:42+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.35-1.el8 started.
backend | Can't connect to MySQL server on 'db' (115)
backend | Can't connect to MySQL server on 'db' (115)
backend | Couldn't create 'fable_backend_development' database. Please check your configuration.
backend | rails aborted!
backend | ActiveRecord::ConnectionNotEstablished: Can't connect to MySQL server on 'db' (115)
backend |
backend |
backend | Caused by:
backend | Mysql2::Error::ConnectionError: Can't connect to MySQL server on 'db' (115)
backend |
backend | Tasks: TOP => db:create
backend | (See full trace by running task with --trace)
backend exited with code 1
db | 2024-01-13 14:39:44+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
解決策
depens_on:にcondition: service_healthyを追記する。
db serviceのhelthチェックがhelthyになったらbackendのコンテナを動作させるようにする。
docker-compose.yml
version: "3.8"
services:
# dbコンテナ
db:
container_name: db
# M1 Macの場合はplatformを指定する
platform: linux/amd64
image: mysql:8.0.35
env_file:
- ./.env
volumes:
- mysql-db:/var/lib/mysql
# - /tmp/dockerdir:/etc/mysql/conf.d/
ports:
- 3306:3306 # コンテナ側:ホスト側
# 文字コード
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
# コンテナが正常に起動したかどうかのチェック
healthcheck:
test:
[
"CMD",
"mysqladmin",
"ping",
"-h",
"localhost",
"-u",
"root",
"--password=$$DB_PASSWORD",
]
interval: 20s
timeout: 10s
retries: 10
docker-yml
# apiコンテナ
api:
depends_on:
db:
condition: service_healthy
解決できない場合
entrypoint.shにdbが起動するまで待機するようにスクリプトを追加することを検討する
entrypoint.sh
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /backend/tmp/pids/server.pid
# データベースが起動するまで待機する
until mysqladmin ping -h "db" -u "root" --password="$DB_PASSWORD" &> /dev/null; do
echo "Waiting for database to become available..."
sleep 2
done
echo "Database is up!"
# コンテナにdb tableを作成
# 本番用ではcreateとseedは1回のみ実行
rails db:create
rails db:migrate
rails db:seed
# Then exec the container's main process (what's set as CMD in the Dockerfile).
# CMD ["rails", "server", "-b", "0.0.0.0"]が実行
exec "$@"
参考