多容器应用程序
多容器应用隔离还是放一起
按照官网的例子:
我现在有一个前端容器, 现在想为它添加一个mysql数据库来让它里面的数据持久化。
我现在是把MySQL放进前端容器吗? 这样就可以在容器中启动MySQL,
但是按照常理来说,每个容器只完成自己的职责是最好的。
那我们就把MySQL放在另一个容器去运行,让它们分开来运行,各人执行各自的职责,这样有什么好处呢?:
- 当您需要对 API 和前端进行不同的扩展,而数据库并不需要,分开后可以各干各的,互不影响。
- 隔离的容器允许你的版本是隔离的,你可以单独升级某一个镜像。
- 虽然您可能会在本地使用容器作为数据库,但是在生产环境中,您可能希望使用托管服务作为数据库。您不希望将数据库引擎与应用程序一起发布。
- 运行多进程需要进程管理器(因为一个容器只能开启一个进程), 这会增加容器开关的复杂度
因此,最好的方式是将容器放在一个网络环境中,而不是一个容器中,下面的图就是例子
将它们放进一个网络,它们就能相互通信;同时,因为处于不同容器,它们又是相互隔离的。
容器网络
docker拥有创建网络的功能及命令。
我们这里使用的Docker网络类型是桥接网络。在桥接网络中,每个容器都分配了一个唯一的IP地址,并且可以通过容器名称或IP地址进行通信。桥接网络还可以通过映射容器端口到主机端口来实现容器与主机之间的通信。
这个通过容器名称来访问是非常有用的,如果使用IP,当你IP发生了改变,那么你的配置就必须改变为当前IP,而使用name是永远不变的,即使容器对应的IP改变了,也不用管。
其次,在同一个网络,我就可以直接通过端口去访问,像后面的例子,MySQL与前端在同一个网络,我前端只用指定主机为它在网络中的名字或者容器的name,然后访问3306端口去连接就行,不需要知道它的实际IP。
查看容器网络
docker network inspect <网络名>
查看网络的信息,在containers可以看到容器的信息
使用容器网络
这里使用的是官网示例:
你需要去下载todo-list项目:git clone github.com/docker/gett…
-
docker network create todo-app
, 创建一个网络空间 -
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:8.0该命令表示:
后台运行
选择网络空间
指定别名
指定卷
指定环境变量:password
指定环境变量要创建的数据库:todos
指定镜像mysql:8.0指定名字这里可以指定别名,或者是使用容器的真实name(该name可以指定也可以docker自动生成)
-
进入
docker exec -it <mysql-container-id> mysql -u root -p
进入容器内部, 后面的是mysql命令 -u, -p 。输入密码后进入容器 -
使用
SHOW DATABASES
可以展示数据库:
- 使用
nicolaka/netshoot
容器,该容器内置了许多有用的工具,可用于故障排除或调试网络问题。
docker run -it --network todo-app nicolaka/netshoot
将该容器加入到network todo-app。
- 查看MySQL
dig mysql
,
7. docker run -dp 127.0.0.1:3000:3000 <br> -w /app -v "$(pwd):/app"
–network todo-app <br> -e MYSQL_HOST=mysql
-e MYSQL_USER=root <br> -e MYSQL_PASSWORD=secret
-e MYSQL_DB=todos <br> node:18-alpine
sh -c “yarn install && yarn run dev”
第一句将端口映射到主机3000端口
第二条命令是指定工作目录
第三条指令是将本地主机的文件系统映射到app目录
第四条指令是将其加入网络 todo-app
重点讲讲环境配置,可以直接往下看,这部分可以跳过
不要误会设置环境变量这里,不是前端设了环境变量就能链接到数据库,而是前端进行了一些处理
真正连接到数据库是因为前端里面有对MySQL的处理,读取环境变量去来配置从而连接MySQL,下面是前端中的设置:
在 Docker 容器中,可以使用 -e
选项来设置环境变量,然后在应用程序中使用 process.env
对象来读取这些环境变量。Docker 会在容器运行时自动将这些环境变量注入到容器的运行时环境中,以便应用程序可以通过 process.env
对象来读取这些环境变量的值。
里面读取了运行容器时添加的环境变量, 然后将它填充到配置中,就可以去初始化MySQL容器了,
前面环境变量配置的host:mysql即是MySQL容器在网络中的名字, docker会它在网络中为什么名字你就输入什么名字MYSQL_HOST=<它的名字>
虽然我们传的是容器在网络中的名字,其实它是把容器名字对应的ip传了进去。
- 运行docker logs -f ,查看链接MySQL是否成功。
-
访问localhost:3000去添加数据
-
进入mysql容器查看数据:
docker exec -it \<MYSQL Containerid\> mysql -p todos
, 然后进行
select * from todo_items;
能看到你添加的数据就成功了。