肯定有很多人问:MySQL运行在哪儿?是安装在相同容器还是单独安装呢?
一般情况下,每一个容器应该只完成一件事情。
原因:
●方便扩展前端和API
●单独容器,可以让当前版本和版本更新隔离开。
●可以让数据分离,本地调试数据库和生产环境的托管数据库分开管理。数据库不必跟随版本一起发布。
●一个容器只能启动一个进程。如果运行多进程。需要增加进程管理器。会增加容器启动和关闭的复杂性。
如下图是我们程序的示意图。待办事项和数据库分开。
一,容器网络
一般情况下,容器是隔离的。它不知道其他进程或者容器。怎么让容器时间通信呢?那就是网络。
如果2个容器在相同的网络里,那么他们可以相互通信。否则不能通讯。
二, 启动MySQL
有2中方式把容器放于网络中。1) 启动时设置网络。2)连接到一个已经存在的网络中。
现在我们先创建网络,然后和MySQL容器启动时连接上。
1.创建网络.
$ docker network create todo-app
2.启动一个MySQL 容器同时挂载到网络中. 首先定义一些环境变量来初始化数据库。
$ docker run -d \ --network todo-app --network-alias mysql \ -v todo-mysql-data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=secret \ -e MYSQL_DATABASE=todos \ mysql:5.7
如果是ARM 比如 Macbook M1 Chips / Apple Silicon,使用如下命令:
$ docker run -d \ --network todo-app --network-alias mysql \ --platform "linux/amd64" \ -v todo-mysql-data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=secret \ -e MYSQL_DATABASE=todos \ mysql:5.7
如果是Windows的PowerShell 请使用如下命令。
PS> docker run -d ` --network todo-app --network-alias mysql ` -v todo-mysql-data:/var/lib/mysql ` -e MYSQL_ROOT_PASSWORD=secret ` -e MYSQL_DATABASE=todos ` mysql:5.7
有一个参数 --network-alias
。请注意。
Tip
我们使用了这个卷
todo-mysql-data
挂载到/var/lib/mysql
, 来存储数据。请注意,我们没有使用 docker volume create命令
Docker 知道我们想用一个命名卷。就自动创建了一个.
3.为了确认我们有数据库启动并运行,连接到数据库并校验连接。
$ docker exec -it <mysql-container-id> mysql -u root -p
需要输入密码时,请注意保密。在 MySQL的shell里,列出数据库并校验你看到了todos
数据库.
mysql> SHOW DATABASES;
输出像这样:
+--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | todos | +--------------------+ 5 rows in set (0.00 sec)
退出mysql。
mysql> exit
todos
可以用啦!
三,连接到MySQL数据库。
数据库起来后。咋连接到容器上呢? 统一网络下,容器咋找到数据库 (每个容器都有自己的IP地址的)?
为了解决这个问题,我们将使用nicolaka/netshoot容器,它附带了许多用于排除故障或调试网络问题的工具。
1.启动一个新的 nicolaka/netshoot 镜像。确定连接到相同网络。
$ docker run -it --network todo-app nicolaka/netshoot
2.容器内部使用 dig
命令, 这是一个非常有用的 DNS 工具。查找mysql的 IP 地址。
$ dig mysql
将会得到类似这样的输出:
; <<>> DiG 9.14.1 <<>> mysql ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32162 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;mysql. IN A ;; ANSWER SECTION: mysql. 600 IN A 172.23.0.2 ;; Query time: 0 msec ;; SERVER: 127.0.0.11#53(127.0.0.11) ;; WHEN: Tue Oct 01 23:47:24 UTC 2019 ;; MSG SIZE rcvd: 44
在“ANSWER SECTION”中,你会看到mysql的一个解析为172.23.0.2的a记录(你的IP地址很可能有不同的值)。虽然mysql通常不是一个有效的主机名,但Docker能够将它解析为具有该网络别名的容器的IP地址(还记得我们前面使用的——network-alias标志吗?)这意味着…我们的应用程序只需要简单地连接到一个名为mysql的主机,它将与数据库对话!没有比这更简单的了!
四,运行你的程序在MySQL上
待办事项的应用程序指定了一些环境变量去连接MySQL。这些参数有:
MYSQL_HOST
- 运行MYSQL的主机名。
MYSQL_USER
- 连接MySQL的用户名。
MYSQL_PASSWORD
- 连接MySQL的密码。
MYSQL_DB
- 连接的数据库
1.请注意: 运行MySQL8.0之上的,请运行如下命令:
mysql> ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY 'secret'; mysql> flush privileges;
2.设置对应的环境变量。
$ docker run -dp 3000:3000 \ -w /app -v "$(pwd):/app" \ --network todo-app \ -e MYSQL_HOST=mysql \ -e MYSQL_USER=root \ -e MYSQL_PASSWORD=secret \ -e MYSQL_DB=todos \ node:12-alpine \ sh -c "yarn install && yarn run dev"
使用ARM based chip, 比如 Macbook M1 Chips / Apple Silicon, 用如下命令
$ docker run -dp 3000:3000 \ -w /app -v "$(pwd):/app" \ --network todo-app \ -e MYSQL_HOST=mysql \ -e MYSQL_USER=root \ -e MYSQL_PASSWORD=secret \ -e MYSQL_DB=todos \ node:12-alpine \ sh -c "apk add --no-cache python2 g++ make && yarn install && yarn run dev"
Windows 请在 PowerShell中运行如下命令。
PS> docker run -dp 3000:3000 ` -w /app -v "$(pwd):/app" ` --network todo-app ` -e MYSQL_HOST=mysql ` -e MYSQL_USER=root ` -e MYSQL_PASSWORD=secret ` -e MYSQL_DB=todos ` node:12-alpine ` sh -c "yarn install && yarn run dev"
3.查看日志 (docker logs
), 能看到如下使用MySQL的信息。
$ nodemon src/index.js [nodemon] 1.19.2 [nodemon] to restart at any time, enter `rs` [nodemon] watching dir(s): *.* [nodemon] starting `node src/index.js` Connected to mysql db at host mysql Listening on port 3000
4.打开浏览器,查看待办事项。
5.连接上数据库,查看数据库数据。
$ docker exec -it <mysql-container-id> mysql -p todos
运行sql命令:
mysql> select * from todo_items; +--------------------------------------+--------------------+-----------+ | id | name | completed | +--------------------------------------+--------------------+-----------+ | c906ff08-60e6-44e6-8f49-ed56a0853e85 | Do amazing things! | 0 | | 2912a79e-8486-4bc3-a4c5-460793a575ab | Be awesome! | 0 | +--------------------------------------+--------------------+-----------+
如果你快速浏览一下Docker Dashboard,你会看到我们有两个应用程序容器在运行。但是,并没有真正的迹象表明它们被组合在一个单独的应用程序中。我们将很快学习到这一章节。
如果觉得阿萨的内容对你有帮助,欢迎围观点赞。