/

在 macOS 上使用 docker 運行 mysql

前言

想測試 mysql 的指令又不喜歡污染自己的機器,docker 是你的好選擇。但是在 docker 跑 mysql 會遇到一些小雷點,在這邊紀錄一下。

正文

起手式,把 mysql 的 image 拉下來
docker pull mysql

之後就可以把 container 跑起來
docker run -p 3306:3306 -d --name mysql -e MYSQL_ROOT_PASSWORD=password mysql

MYSQL_ROOT_PASSWORD 後面那串文字是 root 密碼,在此用 password 舉例,可以換成自己喜歡的

確定跑起來之後,要進去 container 中新建用戶,並且把權限打開 (預設只有 localhost 可以連線)

進入 container:
docker exec -it mysql bash

使用剛才設定的密碼進去 mysql (此指令要在 container 中執行):
mysql -uroot -ppasswd

之後就創建自己想要的用戶,並且設定密碼(在此用 password)。然後要記得把權限打開,除了 localhost 的用戶才連得到

1
2
3
4
5
6
7
mysql> CREATE USER 'yiyu'@'%' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.03 sec)

mysql> GRANT ALL PRIVILEGES ON * . * TO 'yiyu'@'%';
Query OK, 0 rows affected (0.02 sec)

mysql> quit

設定完畢之後就退出 container

再來就會遇到一個雷點!

使用我剛才創建的用戶登入(此指令在 macOS 下執行)

1
2
3
mysql -u yiyu -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

系統會噴一個錯誤出來,而且看起來他是去找 local 的 mysql,但我們的 mysql 不是在 local 而是在 container 之中。

參考了這篇文章:

Unix domain socket 和 TCP/IP socket 的区别

簡單來說就是如果啟動 mysql 去連 localhost 不會真的走 TCP,而是走預設的 UNIX Domain Socket,這樣子可以讓通訊更快,不用拆解封包。

但是我們需要透過 TCP 來讓 localhost 的 3306 port mapping 到 container 中

所以指令應該要指定走 tcp 連線

mysql -h localhost --protocol=tcp -u yiyu -p

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 16
Server version: 8.0.16 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

大功告成!😄

後記

也有另外一種方式是不要用 localhost 而用 127.0.0.1

mysql -h 127.0.0.1 -u yiyu -p

這樣子也會走 tcp 連線

對於 mysql 來說:

  • localhost
  • 空白

就是使用 UNIX Domain Socket