単純なDockerのDB接続で少しハマったのでメモ。
「コンテナ内では正常にDBは使えるけど、ローカルのクライアントツールで接続できない」という事象の対処です。
やろうとしていること
- Dockerを用いてLEMP(Linux+Nginx+MySQL+PHP)環境を構築(済)
- Laravel6.8を導入(済)
- DBクライアントツールTable PlusでローカルからDBに接続 ←ここの話
項目 | バージョン等 |
---|---|
OS | MacOS Big Sur 11.2.1 |
Docker | Docker Desktop 3.3.2 |
DBMS | MySQL 5.7 |
DBクライアント | TablePlus 3.12.6 |
背景
Laravelをインストール後にmigrateやDBクライアントツールでの接続時に、
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
や
Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (0)
や
php_network_getaddresses: getaddrinfo failed: Name or service not known
などなど、いろいろとトラブルが起きて試行錯誤。どうすれば繋がるかだけメモ的に簡潔に記します。
準備と手順
docker-compose.ymlの記述
Dockerfileは作成できている前提で、docker-compose.ymlのDBコンテナの部分の記述を確認していきます。
#docker-compose.ymlのバージョン
version: '3.8'
#docker volumeの設定
volumes:
docker-volume:
#コンテナ(サービス)の設定
services:
#Webコンテナ
web:
image: nginx:1.19
ports:
- '80:80'
depends_on:
- app
volumes:
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
- .:/var/www/html
#アプリケーションコンテナ
app:
build: ./docker/php
volumes:
- .:/var/www/html
#データベースコンテナ
db:
image: mysql:5.7
ports:
- '3333:3306'
environment:
MYSQL_DATABASE: test_db
MYSQL_USER: user
MYSQL_PASSWORD: password
MYSQL_ROOT_PASSWORD: root
volumes:
- docker-volume:/var/lib/mysql
ポイントなのは上記のdb:
のports
のところで、ローカルの3333
ポートで接続(ポートフォワーディング)していること。MySQLのデフォルト3306
が他のプロジェクトと競合したので、今回は適当なポート番号にしています。(別に違う値でも良い)
あとはMYSQL_USERはroot
は使えないのでそれ以外を指定することでしょうか。MYSQL_PASSWORDの方はroot
でOKです。
.envファイルの設定
アプリケーション側の環境ファイルも併せて確認していきます。(今回はLaravelの場合)
~前略~
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=test_db
DB_USERNAME=user
DB_PASSWORD=password
~後略~
docker-compose.ymlの記述ときちんと合わせます。
DB_HOSTは127.0.0.1
ではなくDBコンテナのサービス名のdb
とします。
そして.envファイルを変更したら、
$ docker-compose exec app bash
でコンテナに入り、
$ php artisan config:cache
で設定を取り込む。(Laravelの話ですが)
TablePlusの設定
最後にdocker-compose.ymlや.envで設定した内容でローカル側の接続設定をします。
こちらのHostは127.0.0.1
、Portはローカル側に設定した3333
としています。
設定後、TablePlusの場合はこのようにフォームが緑色になっていれば"接続成功"です..!