docker-compose で作成した MySQL にコンテナ外から mysql コマンドでアクセスしようとしたら Access denied になるにハマったのメモ。※ 本エントリーは経過と事象のメモで詳しく調べてはいません。
環境
Docker コンテナ内の MySQL にコンテナ外からアクセスできない問題
docker-compose.yml
services: db: image: mysql:8.0 ports: - 3306:3306 volumes: - ./mysql/data:/var/lib/mysql - ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf environment: TZ: ${TZ} MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} MYSQL_DATABASE: ${DB_DATABASE} MYSQL_USER: ${DB_USER} MYSQL_PASSWORD: ${DB_PASSWORD}
DB_USER=phper
, DB_PASSWORD=secret
のユーザーを作成するようにしました。
これを docker compose up
したら localhost の 3306
ポートで MySQL が動作している想定です。
外部から MySQL に接続をしてみる
$ mysql -h 127.0.0.1 -P 3306 -u phper -psecret ERROR 1045 (28000): Access denied for user 'phper'@'localhost' (using password: YES)
アクセスできない。
ホストを127.0.0.1
から localhost
に変更してみても同様の状態でした
$ mysql -h localhost -P 3306 -u phper -psecret ERROR 1045 (28000): Access denied for user 'phper'@'localhost' (using password: YES)
Host を localhost
にして --protocol=tcp
を与えるとコンテナ外からアクセス可能になった
$ mysql -h localhost -P 3306 -u phper -psecret --protocol=tcp mysql>
ホストを 127.0.0.1
とすると --protocol=tcp
オプションを与えてもダメだった
$ mysql -h 127.0.0.1 -P 3306 -u phper -psecret --protocol=tcp ERROR 1045 (28000): Access denied for user 'phper'@'localhost' (using password: YES)
root ユーザーだと一見アクセスできているように見えるが、Docker ではなくローカルの MySQL に繋がっていた
root ユーザーだと --protocol=tcp
オプション無しでもアクセスできているように見えていたのですが、Docker コンテナの DB に database を作成してみた結果、phper で Access denied
になっていた時はローカルにある MySQL の DB に繋がっているだけでした。
# local の DB に接続している $ mysql -h 127.0.0.1 -P 3306 -u root -proot mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ # local の DB に接続している $ mysql -h localhost -P 3306 -u root -proot mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ # local の DB に接続している $ mysql -h 127.0.0.1 -P 3306 -u root -proot --protocol=tcp mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ # localhost + --protocol=tcp の時だけ Docker コンテナの DB に接続している $ mysql -h localhost -P 3306 -u root -proot --protocol=tcp mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | my_docker_db | | mysql | | performance_schema | | sys | +--------------------+
root ユーザーの場合ローカルに MySQL をインストールしていると発見が遅れそうなので、show databases;
などで何処に繋がっているのかまでを確認できるようにしておくと良さそうです。
localhost と 127.0.0.1
ホスト名が
localhost
だった場合、パフォーマンスのためなのかソケットが暗黙で使用されます。 ですが。その場合127.0.0.1
を使うとTCP/IP接続が同PCであっても使用され問題なくTCP経由で接続できます。
localhost
を接続先ホストに指定すると、ポート指定のオプションを無視し socket 経由で接続しようとします。
mysql -h localhost -uroot -p --port=3307
こうやった場合でもポート指定が無視されちゃいます。mysql -h 127.0.0.1 -uroot -p --port=3307
この場合はすんなり接続されるはずです
こちらの記事を見た感じだと 127.0.0.1
の方が良さそうな気がしたのですが、今回自分の環境では localhost
+ 明示的に --protocol=tcp
オプションを渡す でしか Docker のコンテナに繋ぐことができませんでした。
ホストは
localhost
と指定するとローカルマシンのmysqlソケットを探しに行くのでエラーになる。
cf. docker内のMySQLに接続したい - かもメモ
以前自分自身で localhost にするとアクセスできなかったという記事を書いているので、今回のは渡されたマシンだったのでマシン側の設定が原因な気もしています。
ネットワークとかの知識が皆無なので、何故なのかという部分は理解できていませんが、発生した事象と解決した方法だけをメモとして残しておくこととしました。(そのうち自分で同じようにハマると思うので…)
[参考]
- DockerのMySQLコンテナに外部のサーバーから接続する - Qiita
- MySQLでlocalhostと127.0.0.1の違い - Qiita
- MySQL ERROR 1045 (28000): Access denied for user 'bill'@'localhost' (using password: YES) - Stack Overflow
- MySQLが起動しない(The server quit without updating PID file ~~~)
- docker-compose と docker サブコマンドの compose って結局どっち使えばいいのかという話 - おおくまねこ