使用Docker进行本地开发,同时支持多个环境

3
我希望使用docker来模拟我们当前的云环境。 我们有大约10个服务(每个服务都有自己的MySQL8数据库,redis,php-fpm和nginx)。目前,每个服务都有一个docker-compose.yml文件,但它们无法相互通信,如果我想测试一个服务需要与另一个服务进行通信的功能,则会出现问题。
我的第一种方法是为每个服务创建一个Dockerfile(并使用新的docker-compose.yml一起运行),使用Debian,但我没有得到很好的结果。 我能够安装nginx(php-fpm和依赖项),但当我到达数据库时,情况变得奇怪了,我感觉这不是正确的做法。
是否可以让一个docker-compose.yml文件“包含”来自各个服务的docker-compose.yml文件?是否有更好的方法?或者我应该坚持使用Dockerfile并在同一个网络上使用docker-compose运行它们呢?

1
您可以使用external网络来配置 docker-compose,即创建项目 A 时使用网络 A,然后创建项目 B 并使用自己的网络和由项目 A 创建的外部网络。在使用外部网络进行配置的项目 B 的服务可以与运行在项目 A 中的服务进行通信。 - masseyb
1
如果您希望在同一网络中启动所有服务(假设它们都使用默认网络配置),则可以使用-f命令行选项COMPOSE_FILE 环境变量来包括所有docker-compose.yml文件中的服务,例如: COMPOSE_FILE=docker-compose.a.yml:docker-compose.b.yml docker-compose up -d 但是请注意,如果多个项目指定相同的服务,则此操作将起到覆盖作用。 - masseyb
1个回答

2

简述

您可以使用external网络配置docker-compose以与其他项目中的服务通信,或者(根据您的项目)使用-f命令行选项 / COMPOSE_FILE环境变量指定compose文件的路径,并在同一网络中启动所有服务。


使用外部网络

给定以下具有项目abtree

.
├── a
│   └── docker-compose.yml
└── b
    └── docker-compose.yml

项目adocker-compose为默认网络设置了一个名称:

version: '3.7'
services:
  nginx:
    image: 'nginx'
    container_name: 'nginx_a'
    expose:
    - '80'
networks:
  default:
    name: 'net_a'

项目b配置使用名为net_b的网络和预先存在的外部网络net_a:

version: '3.7'
services:
  nginx:
    image: 'nginx'
    container_name: 'nginx_b'
    expose:
    - '80'
    networks:
    - 'net_a'
    - 'default'
networks:
  default:
    name: 'net_b'
  net_a:
    external: true

通过在nginx_b容器中执行exec命令,我们可以访问nginx_a容器:

external network service communication

注意:这是一个简化的示例。在尝试启动配置了预先存在网络的环境之前,必须存在外部网络。建议使用覆盖而不是修改现有项目的docker-compose.yml

该配置使nginx_b容器同时进入两个网络:

compose services IP's

使用-f命令行选项

使用-f命令行选项作为覆盖。由于两个文件都指定了一个nginx服务,因此它不能与上述的compose文件一起使用(docker-compose会覆盖/合并第一个nginx服务和第二个服务)。

对于项目a,使用修改后的docker-compose.yml

version: '3.7'
services:
  nginx_a:
    container_name: 'nginx_a'
    image: 'nginx'
    expose:
    - '80'

...并且对于项目b

version: '3.7'
services:
  nginx_b:
    image: 'nginx'
    container_name: 'nginx_b'
    expose:
    - '80'

我们可以在同一个网络中启动这两个环境:docker-compose -f a/docker-compose.yml:b/docker-compose.yml up -d

-f命令行选项


1
两个服务是否使用同名的卷?看起来是这样的情况,第一个实例启动正确,而第二个(挂载相同的卷)无法获取由第一个服务持有的锁。 - masseyb
没错,这就是问题所在。但是卷的名称不应该基于服务名称吗? 一个称为 sc_db,另一个称为 db,两者都有: volumes: - ./env/mysql/data:/var/lib/mysql - Pedro Alca
1
你正在使用本地文件系统的绑定挂载,而不是命名卷。你可以更新每个数据库服务的卷映射,以使用命名卷或在主机上使用不同的路径。例如,将./env/mysql/data:/var/lib/mysql替换为./db_a/mysql/data:/var/lib/mysql,并将./db_b/mysql/data:/var/lib/mysql用于另一个服务,以便服务不会尝试挂载相同的目录。 - masseyb
1
是的,但路径./env/mysql/data相对于运行docker-compose up的位置(如果我没记错的话) 。这里的想法很好,只要这些服务没有挂载相同的卷,您就应该没问题。 - masseyb
1
我刚刚运行了几个测试,发现路径 ./env/mysql/data 是相对于第一个 docker-compose.yml 文件位置(通过 -f 参数传递)的。这给了我一个错误:build path ...\service_a\service_b\.. either does not exist, is not accessible, or is not a valid URL - Pedro Alca
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接