到目前为止,我们一直在使用单容器应用程序。但是,我们现在想将 MySQL 添加到应用程序堆栈中。经常会伴随一些问题——“MySQL 将在哪里运行?安装在同一个容器中还是单独运行?”
一般来说,**每个容器都应该做一件事,并且做好。**几个原因:
还有更多的原因。因此,我们将更新我们的应用程序,使其像这样工作:

默认情况下,容器是独立运行的,对同一台机器上的其他进程或容器一无所知。那么,我们如何让一个容器与另一个容器通信呢?答案是 网络
如果两个容器在同一个网络上,它们可以相互通信。反之,他们就不能相互通信。
有两种方法可以将容器放在网络上:在开始时分配容器或 连接现有容器。现在,我们首先创建网络并在启动时附加 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 的芯片,如苹果的Mac,则使用此命令。
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 中使用此命令。
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
todo-mysql-data的数据卷,并将其安装在 MySQL 存储数据的位置/var/lib/mysqlMYSQL_ROOT_PASSWORD 必需,指定 MySQLroot超级用户帐户设置的密码MYSQL_DATABASE 可选,指定在映像启动时创建的数据库的名称mysql:5.7中的5.7是tag指定的 MySQL 版本的标签
3、要确认我们已启动并运行数据库,请连接到数据库并验证它是否已连接。
$ docker exec -it mysql -u root -p
出现密码提示时,输入secret。
在 MySQL shell 中列出数据库,可以看到todos数据库。
mysql> SHOW DATABASES;
应该看到如下所示的输出:
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| todos |
+--------------------+
5 rows in set (0.00 sec)
退出 MySQL shell 以返回到我们机器上的 shell。
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
输出如图所示:

在ANSWER SECTION中,你将看到解析为 172.23.0.2 的 mysql 的 A 记录( IP 地址可能有不同的值)。
虽然 mysql 通常不是有效的主机名,但 Docker 能够将其解析为具有该网络别名的容器的 IP 地址(我们之前使用的 --network-alias 标志)。
这意味着,我们的应用程序只需要连接到一个名为 mysql 的主机,它就会与数据库对话。
应用程序支持设置一些环境变量来指定 MySQL 连接设置
MYSQL_HOST 正在运行的 MySQL 服务器的主机名MYSQL_USER 用于连接的用户名MYSQL_PASSWORD 用于连接的密码MYSQL_DB 连接后使用的数据库1、注意:对于 MySQL 8.0 及更高版本,请确保在 mysql中运行以下命令:
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"
如果使用的是 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、如果我们查看容器的日志,我们应该会看到一条消息,表明它正在使用 mysql 数据库。
$ docker logs

4、在浏览器中打开应用程序,然后将一些项目添加到的待办事项列表中。

5、连接 mysql 数据库并证明项目正在写入数据库。记住,密码是加密的。
$ docker exec -it mysql -p todos

在 mysql shell 中,运行以下命令:
mysql> select * from todo_items;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YOMZkUlH-1659600598560)(https://raw.githubusercontent.com/yuyun-21/uplod-images/hyh/images/Flowable/image-20220620114323914.png)]
如果快速查看 Docker 仪表板,会发现我们有两个应用程序容器正在运行。但是,没有真正的迹象表明它们在一个应用程序中组合在一起。
