我应该/可以如何避免Docker的重复部分构成多个相互依赖项目的文件

我应该/可以如何避免Docker的重复部分构成多个相互依赖项目的文件,docker,docker-compose,development-environment,Docker,Docker Compose,Development Environment,让我们以一个依赖于两个或更多API的移动应用程序为例 每个项目都在独立的Git存储库中分开。然后我们有3个存储库,允许我们并行开发每个存储库 每个项目都有自己的依赖关系: 例如,第一个API需要一个SQL数据库 第二个API需要一个NoSQL数据库 移动应用程序需要这两个API 现在我想“dockerize”所有这些项目,以简化开发环境,并在开发人员和/或生产环境之间统一开发环境 目前,在每个项目中,我们可以创建一个自定义的docker compose.yml文件,用于处理每个项目的需求 例

让我们以一个依赖于两个或更多API的移动应用程序为例

每个项目都在独立的Git存储库中分开。然后我们有3个存储库,允许我们并行开发每个存储库

每个项目都有自己的依赖关系:

  • 例如,第一个API需要一个SQL数据库
  • 第二个API需要一个NoSQL数据库
  • 移动应用程序需要这两个API
现在我想“dockerize”所有这些项目,以简化开发环境,并在开发人员和/或生产环境之间统一开发环境

目前,在每个项目中,我们可以创建一个自定义的
docker compose.yml
文件,用于处理每个项目的需求

例如,在第一个API中

version: "3.7"

services:
  first_api:
    image: golang:1.13
    working_dir:
      - /src
    depends_on:
      - mysql
    volumes:
      - ".:/src"
    command: go run main.go

  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_USER_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE_NAME}

  adminer:
    image: adminer
    restart: always
第二个API将有一个类似的
docker compose.yml
文件,但改用NoSQL DB

然后,在移动应用程序存储库中,我们将有一个
docker compose.yml
文件,其中包含大量重复的代码(和完全相同的容器),因为它与其他两个API相互依赖,还有一些其他文件标识(例如
.env
文件、入口点脚本,如果需要…)

数据库设置/种子设定也将在2个存储库上完成,这可能有点烦人

docker compose.yml
文件如下所示:

version: "3.7"

services:
  app:
    build:
      context: .
      args:
        - IP=${IP}
    ports:
      - 19000:19000
      - 19001:19001
      - 19002:19002
    volumes:
      - ".:/app"
    depends_on:
      - first-api
      - second-api

  first-api:
    image: my-registry:5000/first-api
    ports:
      - 9009:3000
    depends_on:
      - mysql
    volumes:
      - ".env:/dist/.env"

  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_USER_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE_NAME}

  adminer:
    image: adminer
    restart: always
    ports:
      - 9099:8080

  second-api:
    image: my-registry:5000/second-api
    ports:
      - 9010:3000
    depends_on:
      - mongo

  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGO_ROOT_USERNAME}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_ROOT_PASSWORD}

  mongo-express:
    image: mongo-express
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: ${MONGO_ROOT_USERNAME}
      ME_CONFIG_MONGODB_ADMINPASSWORD: ${MONGO_ROOT_PASSWORD}
事实上,在这个最终的
docker compose
文件中,我们有4个容器定义,在API的配置中与它们完全相同,我们还将一些环境变量复制并在至少2个存储库中进行版本控制

有时我们也可以根据具体情况复制
Dockerfile
,数据库设置等

我是否在Docker开发环境设置中遗漏了一些可以避免重复的内容

是否有避免这种情况的最佳做法或建议


具有大型相互依存微服务体系结构的公司如何管理这些相互依存关系?

您可以将YAML锚定和别名用于

以下是另外两篇文章,提供了有关这方面的有用细节:


您可以将YAML锚定和别名用于

以下是另外两篇文章,提供了有关这方面的有用细节:


我可能会通过独立运行两个单独服务的Docker Compose文件,然后在前面运行一个将它们连接在一起的代理来设置。您可以从其他
docker compose.yml
文件中“借用”网络。你现在差不多有这个了;代理将是您的“应用”容器,您可以使用对其他应用程序的
default
网络的引用

version: '3'
services:
  app:
    build: .
    environment:
      - IP=${IP}
    ports:
      - 19000:19000
      - 19001:19001
      - 19002:19002
    networks:
      - firstapi_default
      - secondapi_default
networks:
  firstapi_default:
    external: true
  secondapi_default:
    external: true
如果您有多个独立需要MySQL数据库后端的服务,这种方法也可以工作;在每个项目目录中运行单独的
docker compose up
,将为每个项目实例化一个新的单独数据库。(在微服务体系结构中,服务之间通常不共享数据存储;它们仅通过API进行通信。)


如果您的一个后端服务需要调用另一个后端服务,那么您很快就会遇到扩展问题,Docker Compose可能不是合适的工具。是一项重要的承诺,但它将允许您将这些单独的服务部署到单独的命名空间中,然后使用DNS名称,如
first\u api.first\u namespace.svc.cluster.local
,在它们之间进行通信。

我可能会通过独立运行两个单独服务的Docker Compose文件来设置这一点,然后在前面运行一个代理将它们连接在一起。您可以从其他
docker compose.yml
文件中“借用”网络。你现在差不多有这个了;代理将是您的“应用”容器,您可以使用对其他应用程序的
default
网络的引用

version: '3'
services:
  app:
    build: .
    environment:
      - IP=${IP}
    ports:
      - 19000:19000
      - 19001:19001
      - 19002:19002
    networks:
      - firstapi_default
      - secondapi_default
networks:
  firstapi_default:
    external: true
  secondapi_default:
    external: true
如果您有多个独立需要MySQL数据库后端的服务,这种方法也可以工作;在每个项目目录中运行单独的
docker compose up
,将为每个项目实例化一个新的单独数据库。(在微服务体系结构中,服务之间通常不共享数据存储;它们仅通过API进行通信。)

如果您的一个后端服务需要调用另一个后端服务,那么您很快就会遇到扩展问题,Docker Compose可能不是合适的工具。是一项重要的承诺,但它将允许您将这些单独的服务部署到单独的命名空间中,然后使用DNS名称,如
first\u api.first\u namespace.svc.cluster.local
,在它们之间进行通信