結論
docker run --name sample-app-db -e MYSQL_ROOT_PASSWORD=root -d -p 3306:3306 mysql:latest
mysql -h 127.0.0.1 -P 3306 -u root -proot
# コンテナにアタッチしてMySQL接続
docker exec -it sample-app-db bash
mysql -u root -proot
※ MySQLで-pオプションに直接パスワードを打つと現場によってはめっちゃ怒られます。遊びでのみ利用しましょう。
説明
MySQLコンテナ起動
ここで大切なことは-pオプションでクライアント側のポート3306がゲストOS側の3306ポートにつながるように設定してやることだけです。
これを指定してやらないと外部からコンテナにアクセスすることはできません。
他は、MySQLの公式dockerhubのサンプルをほとんどそのまま利用しました。
クライアントから接続
ここで大切なことはホストに127.0.0.1
を指定することです。
なぜ127.0.0.1
にしないといけないのかは、よくわかりませんでした。
以下のリンクを参考に指定しました。
https://qiita.com/saken649/items/00e752d89f2a6c5a82f6#sql%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%8B%E3%82%89%E3%81%AE%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9
また、MySQLはポートを指定しない場合はデフォルトで3306が指定されるため今回のケースでは指定しなくても問題ありません。
読まなくてもいいこと
以降は私のグチを交えて、どうやってこの結論に至ったのかをタラタラ書きます。
暇すぎてどうしようもない時に読んでください。
結論に至るまで
1. dockerhubでMySQLコンテナの起動コマンドを確認
以下の公式ページからとりあえず起動コマンドを確認し自分好みにパラメータを書き換えました。
https://hub.docker.com/_/mysql
docker run --name sample-app-db -e MYSQL_ROOT_PASSWORD=root -d mysql:latest
2. クライアントから接続を試みるが失敗
$ mysql -h sample-app-db -u root -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2005 (HY000): Unknown MySQL server host 'sample-app-db' (8)
直感的にホスト名ってコンテナ名じゃね?ってな感じで実行するとsample-app-db
なんてホストは無いとエラーが出ました。
コンテナにアタッチしてMySQL接続はできるのですが、クライアントから接続ができませんでした。
3. 神記事との出会い
え?じゃホストって何指定したらええねん?って思いdocker mysql ホスト名指定
でググってみると、以下の記事がヒットしました。ホスト名を指定してコンテナを立ち上げる方法を調べるための検索単語でしたが、クライアント側でどんなホスト名を指定したらいいかが記述されていました。
https://qiita.com/saken649/items/00e752d89f2a6c5a82f6
この記事の内容を一部引用させていただくとMySQLコマンドのパラメータは以下のように設定するとのこと。
- Host: 127.0.0.1
- User: root
- Password: your_password
- Port: 3306
上記により改めてコマンドを組み直し実行してみました。
$ mysql -h 127.0.0.1 -P 3306 -u root -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
はい、予想通りうまく動きませんね。
4. エラーメッセージをAccess denied for user 'root'@'localhost' (using password: YES)をググる
エラーメッセージ的にアクセスが拒否されているっぽい。ググってみたけれどよくわからなかった。パスワードもあってそうだし、ホストをlocalhost
にしてもダメ。ハマりそうだったので、一旦コンテナ起動コマンドについて考え直してみることにしました。
5. いろんなサイトで「3306:3306」って記述をよく見るぞ
調べている中で出回っている情報の多くがdocker-compose
を利用した内容でした。
なのでdocker-compose.yml
ファイルを良く目にしたのですが、その中で以下の記述をよくみました。
xxx-db:
ports:
- 3306:3306
これってコンテナ起動時に指定してやらないといけないんじゃね?って思い早速コンテナ起動コマンドを以下のようにポートを指定するように修正。
docker run --name sample-app-db -e MYSQL_ROOT_PASSWORD=root -d -p 3306:3306 mysql:latest
以上で思った通りの動作をさせることができました。
番外編:新たな問題
以下のコマンドでもクライアントからDBに接続することができます。
mysql -h localhost -P 3306 --protocol=tcp -u root -proot
しかしこのコマンドを実行してから従来のコマンドを実行しても接続できなくなりました。
$ mysql -h 127.0.0.1 -P 3306 -u root -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
なぜコンテナは拗ねてしまったのでしょうか?誰か助けてほしいです。