多Docker Compose文件下避免MySQL容器DNS重名的方法
这是个非常常见的场景——当你用多个独立的docker-compose文件部署带MySQL的服务,又要求所有服务处于同一网络时,同名服务的DNS冲突确实让人头疼。下面给你几个实用的解决办法,按需选择:
方法一:启动时指定不同的Compose项目名(最省心,无需改配置)
Docker Compose默认会用当前目录名作为项目标识,同一网络下,不同项目的服务可以通过服务名.项目名的格式来访问。你只需要在启动每个compose文件时,用-p参数指定唯一的项目名即可:
比如启动第一个服务:
docker-compose -p service1 -f service1.yml up -d
启动第二个服务:
docker-compose -p service2 -f service2.yml up -d
这样,在同一anetwork网络中,其他服务可以用mysql.service1访问第一个数据库,用mysql.service2访问第二个数据库。而每个compose内部的应用服务,依然可以用mysql这个服务名访问自己对应的数据库(Compose内部的服务解析优先)。
这个方法的好处是完全不需要修改现有的docker-compose文件,非常适合不想改动配置的场景。
方法二:给每个MySQL服务配置专属网络别名
如果你希望有更直观的DNS名称,可以在每个docker-compose文件中,给MySQL服务添加网络别名(aliases)。这样即使服务名还是mysql,在共享网络中也能通过别名区分:
修改service1.yml:
version: '2' services: mysql: image: mysql networks: anetwork: aliases: - mysql-service1 # 自定义第一个数据库的别名 networks: anetwork: external: true # 假设anetwork是预先创建的外部网络
修改service2.yml:
version: '2' services: mysql: image: mysql networks: anetwork: aliases: - mysql-service2 # 自定义第二个数据库的别名 networks: anetwork: external: true
之后,网络中的其他服务就可以用mysql-service1和mysql-service2分别访问对应的数据库,每个compose内部的应用依然可以用mysql访问自己的数据库。
方法三:直接修改服务名称(最直观,适合长期维护)
如果愿意调整docker-compose文件,直接给每个MySQL服务设置唯一的名称是最直观的方式,从根源上避免重名:
修改service1.yml:
version: '2' services: mysql-service1: # 把服务名改成唯一标识 image: mysql networks: - anetwork networks: anetwork: external: true
修改service2.yml:
version: '2' services: mysql-service2: # 第二个服务用不同的名称 image: mysql networks: - anetwork networks: anetwork: external: true
注意:这种方式需要同步修改对应应用服务中的数据库连接地址(比如把原来的mysql改成mysql-service1),适合愿意统一规范服务命名的场景。
额外注意事项
- 确保共享网络
anetwork是预先创建的(执行docker network create anetwork),或者在其中一个compose文件中创建网络,其他compose文件将其声明为external: true。 - 如果需要把MySQL端口暴露到宿主机,记得给每个服务分配不同的宿主机端口(比如service1用
3306:3306,service2用3307:3306),避免端口冲突。
内容的提问来源于stack exchange,提问作者Guillaume LUNIK

