【问题标题】:Docker Compose - How to make 'working_dir' configurableDocker Compose - 如何使“working_dir”可配置
【发布时间】:2020-12-09 14:47:45
【问题描述】:

我有以下问题,您可能无法提出解决方案。

在我工作的项目中,我们有复杂的软件系统,依赖于 akka、kafka、cassandra,为了能够测试这些系统,我们准备了 docker 容器,将它们组织为基础设施组件和业务组件。

基础设施组件,如 kafka、cassandra 等,被组织在专用的 GiT 存储库中,业务组件在其专用的 GiT 存储库中......我们不想将基础设施 docker-compose 文件放在业务组件 GiT 存储库中,因为那里其中 200 多个,访问每个存储库并维护基础架构“docker-compose.yml”文件将是一场噩梦。

例如,以下是基础架构的“docker-compose”、kafka(zookeeper、schema_registry、broker)和 cassandra,它们将位于目录“/some_directory/myproject/infrastructure/docker-compose.yml”中。

version '3'
services:
   zookeeper: 
      working_dir: /some_directory/myproject/infrastructure
      image: confluentinc/cp-zookeeper:6.0.1
      container_name: my_zookeeper
      hostname: zookeeper
      ports:
         - "2181:2181"
      environment:
         ZOOKEEPER_CLIENT_PORT: 2181
      volumes:
         - /c/somedirectory/myproject/infrastructure/zookeeper/zookeeper.properties:/etc/zookeeper/zookeeper.properties

   broker:
      working_dir: /some_directory/myproject/infrastructure
      image: confluentinc/cp-enterprise-kafka:6.0.1
      container_name: my_broker
      hostname: broker
      depends_on:
         - zookeeper
      ports:
         - "9092:9092"
      environment:
         KAFKA_BROKER_ID: broker_1
         KAFKA_ZOOKEEPER_CONNECT: "zookeeper:2181"
         KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
         KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker:9092,PLAINTEXT_HOST://localhost:9092
      volumes:
         - /c/somedirectory/myproject/infrastructure/broker/server.properties:/etc/broker/server.properties

   schema-registry:
       working_dir: /some_directory/myproject/infrastructure
       image: confluentinc/cp-schema-registry:6.0.1
       container_name: my_schema-registry
       hostname: schema-registry
       depends_on:
          - zookeeper       
          - broker
       ports:
          "8081:8081"
       environment:
           SCHEMA_REGISTRY_HOST_NAME: schema-registry
           SCHEMA_REGISTRY_LISTENERS: http://0.0.0.0:8081
       volumes:
           -/c/somedirectory/myproject/infrastructure/schema_registry/schema-registry.properties:/etc/schema_registry/schema-registry.properties

  cassandra:
     working_dir: /some_directory/myproject/infrastructure
     image: cassandra:3.11.8
     container_name: my_cassandra
     hostname: cassandra
     ports:
        "9042:9042"
     volumes:
        - /c/somedirectory/myproject/infrastructure/cassandra/cassandra.yml:/etc/cassandra/cassandra.yml

在业务组件 GiT 存储库中,我将有一个 Spring Boot 应用程序,我将作为 3 个集群部署到 Docker,在目录 '/some_business_component_directory/myproject/infrastructure/docker-compose. yml'。

version '3'
services:
   my_app_1:
       image: mycompany/myapp
       init: true
       hostname: myapp1
       container_name: my_app1
       depends:
          - zookeeper 
          - broker
          - schema-registry
          - cassandra
       ports:
          "2552:2552"
       environment:
          CONFIG_FORCE_akka_cluster_seed__nodes.0: "akka://myapp@myapp1:2552"
          CONFIG_FORCE_akka_cluster_seed__nodes.1: "akka://myapp@myapp2:2553"
          CONFIG_FORCE_akka_cluster_seed__nodes.2: "akka://myapp@myapp3:2554"
          CONFIG_FORCE_akka_remote_artery_canonical_hostname: "myapp1"
          CONFIG_FORCE_akka_remote_artery_canonical_port: "2552"
          KAFKA_BORKER_URL: "broker:9092"
          CASSANDRA_URK: "cassandra:9042"

   my_app_2:
       image: mycompany/myapp
       init: true
       hostname: myapp2
       container_name: my_app2
       depends:
          - zookeeper 
          - broker
          - schema-registry
          - cassandra
       ports:
          "2553:2553"
       environment:
          CONFIG_FORCE_akka_cluster_seed__nodes.0: "akka://myapp@myapp1:2552"
          CONFIG_FORCE_akka_cluster_seed__nodes.1: "akka://myapp@myapp2:2553"
          CONFIG_FORCE_akka_cluster_seed__nodes.2: "akka://myapp@myapp3:2554"
          CONFIG_FORCE_akka_remote_artery_canonical_hostname: "myapp1"
          CONFIG_FORCE_akka_remote_artery_canonical_port: "2553"
          KAFKA_BORKER_URL: "broker:9092"
          CASSANDRA_URK: "cassandra:9042"

services:
   my_app_3:
       image: mycompany/myapp
       init: true
       hostname: myapp3
       container_name: my_app3
       depends:
          - zookeeper 
          - broker
          - schema-registry
          - cassandra
       ports:
          "2554:25524
       environment:
          CONFIG_FORCE_akka_cluster_seed__nodes.0: "akka://myapp@myapp1:2552"
          CONFIG_FORCE_akka_cluster_seed__nodes.1: "akka://myapp@myapp2:2553"
          CONFIG_FORCE_akka_cluster_seed__nodes.2: "akka://myapp@myapp3:2554"
          CONFIG_FORCE_akka_remote_artery_canonical_hostname: "myapp1"
          CONFIG_FORCE_akka_remote_artery_canonical_port: "2552"
          KAFKA_BORKER_URL: "broker:9092"
          CASSANDRA_URK: "cassandra:9042"

从环境变量可以看出

          KAFKA_BORKER_URL: "broker:9092"
          CASSANDRA_URK: "cassandra:9042"

我必须结合使用 2 个 'docker-compose 文件

/some_business_component_directory/myapp> docker-compose -f /some_business_component_directory/myapp/docker-compose.yml -f /some_directory/myproject/infrastructure/docker-compose.yml  up -d

    

您现在可能在这里看到了我不喜欢的内容,而我的业务组件“docker-compose”需要来自基础设施组件的“主机名”(我认为这是将它们放置在同一网络下的唯一方法),我必须同时使用 'docker-compose.yml' 文件,但这意味着我不能在基础设施组件'docker-compose' 中使用相对路径(如果我使用它,则使用上述 docker-compose 命令解析所有相对路径基于“/some_business_component_directory/myapp”)。

所以我必须在基础结构“docker-compose.yml”中写入每条路径,这是我不喜欢的,因为对于从 Git 中提取代码的每个开发人员来说,URL 的“/some_directory”部分可能不同。

docker a la Maven '${project.basedir}' 中的变量在这里会很好吗?你知道解决这个问题的优雅方法,所以我不必使用绝对路径。

谢谢回答...

【问题讨论】:

    标签: docker docker-compose dockerfile


    【解决方案1】:

    您可以将一个 Compose 文件的 default 网络设置为另一个。此设置在 Docker 文档中的 Networking in Compose 中有简要描述。如果您知道第一个docker-compose.yml 文件位于名为infrastructure 的目录中,并且其default 网络名为infrastructure_default(与docker network ls 仔细检查),那么您可以在第二个docker-compose.yml 文件中指定

    # at the top level
    networks:
      default:
        external:
          name: infrastructure_default
    

    现在docker-compose.yml 文件中的所有容器都将位于同一网络上,因此它们可以解析彼此的 Compose 服务名称。

    一旦你有了这个,你就可以将每个 Compose 文件中的 volumes: 挂载设置为相对路径,它们将相对于它们自己的 docker-compose.yml 文件进行解释。

    # infrastructure/docker-compose.yml
    version: '3.8'
    services:
      broker:
        volumes:
          # relative to the directory containing this file
          - ./broker/server.properties:/etc/broker/server.properties
    
    # application/docker-compose.yml
    version: '3.8'
    services:
      my_app_1:
        environment:
          KAFKA_BROKER_URL: 'kafka://broker:9092'
    networks:
      default:
        external:
          name: infrastructure_default
    

    正常使用不需要设置container_name:hostname:;仍然可以使用它们的 Compose 服务名称访问服务。 ports: 不是容器间通信所必需的(但如果您需要使用 kafka-console-consumer 之类的东西从主机进行调试,则确实需要它)。你不能 depends_on: 像这样在不同的 docker-compose.yml 文件中声明的容器;可以盲目断言它已经在运行。

    【讨论】:

    • 感谢您的回答,通过您对网络部分的修改,我实现了我想要的,我可以分别启动 2 个 'docker-compose' 文件,业务组件可以首先看到网络和路径文件可以保持相对。这是否意味着在我的版本中不使用绝对路径是不可能的?我在我的版本中更喜欢的东西是,开发人员只需一个命令即可启动两个“docker-compose”文件(这种方式“取决于”业务组件也可以工作)。分别启动两个文件并不是世界末日,我只想知道我是否可以摆脱 abs 路径
    • docker-compose -f documentation 指出,所有文件中的所有相对路径都是相对于第一个文件的位置进行解释的。我不知道有什么办法可以解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2019-08-17
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多