Docker 目录挂载 & 多容器通信

109 阅读3分钟

Docker 目录挂载 & 多容器通信

目录

[TOC]

🥙目录挂载

现存问题
  • 使用 Docker 运行后,我们改了项目代码不会立刻生效,需要重新 buildrun ,很是麻烦。
  • 容器里面产生的数据,例如 log 文件,数据库备份文件,容器删除后就丢失了。

目录挂载解决以上问题

几种挂载方式
  • bind mount 直接把宿主机目录映射到容器内,适合挂代码目录和配置文件。可挂到多个容器上
  • volume 由容器创建和管理,创建在宿主机,所以删除容器不会丢失,官方推荐,更高效,Linux 文件系统,适合存储数据库数据。可挂到多个容器上
  • tmpfs mount 适合存储临时文件,存宿主机内存中。不可多容器共享。

文档参考: Manage data in Docker | Docker Docs

image.png
挂载演示

bind mount 方式用绝对路径 -v D:/code:/app

volume 方式,只需要一个名字 -v db-data:/app

示例:
docker run -p 8080:8080 --name test-hello -v D:/code:/app -d test:v1

注意!
因为挂载后,容器里的代码就会替换为你本机的代码了,如果你代码目录没有 node_modules 目录,你需要在代码目录执行下 npm install --registry=https://registry.npm.taobao.org 确保依赖库都已经安装,否则可能会提示“Error: Cannot find module ‘koa’”
如果你的电脑没有安装 nodejs ,你需要安装一下才能执行上面的命令。

👨‍👦‍👦多容器通信

学习目标

项目往往都不是独立运行的,需要数据库、缓存这些东西配合运作。
这节我们把前面的 Web 项目增加一个Redis依赖,多跑一个 Redis 容器,演示如何多容器之间的通信。

创建虚拟网络

要想多容器之间互通,从 Web 容器访问 Redis 容器,我们只需要把他们放到同个网络中就可以了。

文档参考: docker network | Docker Docs

演示
创建一个名为test-net的网络:

docker network create test-net

运行 Redis 在 test-net 网络中,别名redis

docker run -d --name redis --network test-net --network-alias redis redis:latest

修改代码中访问redis的地址为网络别名
 
 
// 配置端口号
const PORT = 8089
//引入了Redis库
const redis = require('redis')
// 创建了一个Redis客户端实例
let rds = redis.createClient({
	url: "redis://redis:6379"
})
// 监听了连接成功的事件,并在连接成功时打印了一条成功连接的消息
rds.on('connect', () => {
	console.log('redis connect success');
})
// 连接到Redis数据库。
rds.connect()
// 1.安装 npm install --save koa-router
var Koa = require('koa');
// 2.引入路由并实例化
var Router = require('koa-router');
var app = new Koa();
var router = new Router();
 
// 路由路径前缀设置
router.prefix('/api')
 
// 3.配置路由
router.get('/', async (ctx) => { // 路径: /api/get
	// 返回数据给前端
	ctx.body = "index page";
});
 
router.all('/hello/:name', ctx => {
	let name = ctx.params.name
	ctx.body = `hello  ${name ? name : 'world'}`
})
router.all('/redis', async ctx => {
	// 它首先使用rds.incr('count')来对名为'count'的键进行自增操作,然后将得到的值赋给变量
	let count = await rds.incr('count')
 
	ctx.body = `on test redis page, 44 count ${count}`
})
// 4.启动路由(来自于官方文档);
// router.allowedMethods()可以配置也可以不配置。
// 如果之前的没有设置响应头,配置此选项以后可以自动设置响应头。
app.use(router.routes()).use(router.allowedMethods());
 
// 监听端口
app.listen(PORT, () => {
	console.log(`本地服务器启动成功,http://localhost:${PORT}`)
})
运行 Web 项目,使用同个网络

docker run -p 8080:8080 --name test -v D:/test:/app --network test-net -d test:v1

查看数据

http://localhost:8080/redis
容器终端查看数据是否一致

更多相关命令

docker ps 查看当前运行中的容器
docker images 查看镜像列表
docker rm container-id 删除指定 id 的容器
docker stop/start container-id 停止/启动指定 id 的容器
docker rmi image-id 删除指定 id 的镜像
docker volume ls 查看 volume 列表
docker network ls 查看网络列表