【问题标题】:Docker - Reuse docker-compose configurations for different projectsDocker - 为不同的项目重用 docker-compose 配置
【发布时间】:2020-08-05 10:08:54
【问题描述】:

我有一个大型 Docker 项目,其 Dockerfiles for nginx, apache2, varnish, redis 经过数周的更改和测试后配置并运行良好。

我现在正在设置项目以使用 docker-compose 和 override.yml 文件以便于设置:

我正在尝试对多个项目(网站)使用相同的 docker-compose 设置

正常启动(使用docker-compose.yml and optional docker-compose.override.ymldocker-compose up -d

自定义启动(使用特定的 docker-compose 文件) docker-compose -f docker-compose.yml -f custom/docker-compose.website1.yml up -d

这两种方法都可以正常启动: docker-compose ps

忽略它们是 0 号出口这一事实 - 我使用 docker-compose stop, the containers work fine 阻止了它们 nginx-proxy /usr/bin/supervisord 退出 0 redis-cache /usr/bin/supervisord 退出 0 清漆缓存 /usr/bin/supervisord 退出 0 web-server-apache2 /usr/bin/supervisord 退出 0

现在我想要一个第二个项目(网站)来使用相同的 docker/docker-compose 配置设置:

docker-compose -f docker-compose.yml -f anothercustomfolder/docker-compose.website2.yml up -d

令我惊讶的是 docker-compose 重新创建了容器并且不创建新的容器集:

请参阅“当前设置”部分了解我如何设置。

  Creating network "delete-network-frontend" with the default driver
  Recreating nginx-proxy        ... done
  Recreating varnish-cache      ... done
  Recreating web-server         ... done
  Recreating redis-cache        ... done

在第二个安装文件夹中运行docker-compose ps 时:

注意名称和上面不一样(这是第二个测试设置)

         Name                       Command          State                Ports
  ------------------------------------------------------------------------------------------------
  nginx-proxy-delete       /usr/bin/supervisord   Up      0.0.0.0:443->443/tcp,
                                                          0.0.0.0:80->80/tcp
  redis-cache-delete       /usr/bin/supervisord   Up      0.0.0.0:6379->6379/tcp
  varnish-cache-delete     /usr/bin/supervisord   Up      0.0.0.0:6081->6081/tcp,
                                                          0.0.0.0:6082->6082/tcp
  web-server-              /usr/bin/supervisord   Up      0.0.0.0:8080->8080/tcp
  apache2-delete

看来 docker-compose 做了两件事:1. 重新创建(替换)项目 1 容器,使用项目 1 容器名称来提及它们已“重新创建”,以及 2. 删除项目 1 容器,将其重命名为项目 2 个容器。

当前设置

  • 我创建了一个完整的 Dockerfile 项目,配置了 docker-compose.yml 和两个覆盖 docker-compose 文件 (docker-compose.website1.yml and docker-compose.website2.yml`)。
  • 我制作了一个工作 Dockerfile / docker-compose.yml 项目的完整副本并创建了一个新文件夹:换句话说,它们都将使用 相同的 docker 设置,但使用不同的 docker -compose.yml 覆盖文件/var/www/docker/site1 /var/www/docker/site2

问题

TLDR:我如何在同一个主机操作系统上为多个项目使用工作中的docker-compose 项目...而不用它替换另一个项目的容器。

我希望能够同时看到(使用两者),例如能够看到这个: 忽略此处端口相同的事实,我知道它们不会同时运行,我将在此工作时更新项目 docker-compose.yml 自定义文件

docker-compose ps

               Name                       Command          State                Ports
  ------------------------------------------------------------------------------------------------
  nginx-proxy              /usr/bin/supervisord   Up      0.0.0.0:443->443/tcp,
                                                          0.0.0.0:80->80/tcp
  redis-cache              /usr/bin/supervisord   Up      0.0.0.0:6379->6379/tcp
  varnish-cache            /usr/bin/supervisord   Up      0.0.0.0:6081->6081/tcp,
                                                          0.0.0.0:6082->6082/tcp
  web-server-              /usr/bin/supervisord   Up      0.0.0.0:8080->8080/tcp
  apache2
  nginx-proxy              /usr/bin/supervisord   Up      0.0.0.0:443->443/tcp,
                                                          0.0.0.0:80->80/tcp
  redis-cache-delete       /usr/bin/supervisord   Up      0.0.0.0:6379->6379/tcp
  varnish-cache-delete     /usr/bin/supervisord   Up      0.0.0.0:6081->6081/tcp,
                                                          0.0.0.0:6082->6082/tcp
  web-server-              /usr/bin/supervisord   Up      0.0.0.0:8080->8080/tcp
  apache2-delete

如果有人问:为什么不把网站放在同一个(一个)容器中??

对于有人可能会问这个的可能性,我知道我可以将多个网站添加到/etc/apache2/sites-enabled(或 nginx)中,并在每个站点的 Dockerfile 中使用 ADD 添加自定义配置文件,但使用该方法我 无法测试不同的轻微设置

可以通过在“覆盖 docker-compose 文件”中引用另一个不同的图像来使用不同的设置

例如,我可以创建一个 Dockerfile 来安装 所需的所有 php7.3 库并在其上运行 Magento 2.3,然后有另一个 Dockerfile 来 测试 php7.4,并运行另一个PHP5.6 安装上的旧 Magento 1 站点等等

【问题讨论】:

  • 只是想看看是否有人对使用具有相同 docker-compose 项目配置的多个项目有建议
  • 你是从同一个目录运行这一切吗?您是否设置了COMPOSE_PROJECT_NAME 环境变量?您是否覆盖了 docker-compose.yml 文件中的 container_name:
  • 我想我是从两个不同的文件夹运行它的。将看看COMPOSE_PROJECT_NAME,对此不确定 - 构建我将使用docker-compose build --no-cache --build-arg ARG_I_NEED=val 并用于创建容器:(具有覆盖值)docker-compose -f docker-compose.yml -f docker-compose.overrides/docker-override-webserver1.yml up -d
  • 参考您刚刚提供的关于container_name 的其他答案,是的,我愿意:This docker question
  • 是的,docker-compose -p$COMPOSE_PROJECT_NAME 做同样的事情。您需要记住将 -p 选项提供给 every docker-compose 命令。

标签: docker docker-compose dockerfile


【解决方案1】:

感谢 David Maze 的建议,我在配置 docker-compose 设置以处理多个项目方面更加努力。

基于 docker-compose v1.25.0(2020 年 7 月)的信息

当您想要重用(持久化)您的容器(启动/停止而不是仅向上/向下 - 删除)时,此讨论尤其重要

正如我最初在我的问题中指出的那样 - 如果您尝试使用 docker-compose up -d 创建容器,那么该工具目前根本不支持一些陷阱。

陷阱

当前 Docker 组合实现的缺陷:

  1. 如果您只是将覆盖的docker-compose*.yml不同的容器名称(每个“项目”)同一文件夹中的文件一起使用

docker-compose up 将简单地替换现有容器,如我的问题中所述。

  1. 您可以执行以下操作:docker-compose -p CUSTOM_PROJECT_NAME -f file1.yml -f file2.yml up -d,但是:

这本身是没有用的 - 这些容器只会在你想要停止它们之前工作。 只要你想做docker-compose start(重新启动现有的容器集) em> 它只会以 Error: No containers to start

失败
  1. 如果您使用两个不同的文件夹具有相同的 docker-compose 项目(即克隆项目): 例如 ./dc-project1 ./dc-project2 但在 container_name 中使用 container_name 字段docker-compose.*.yml file:李>

当您尝试在./dc-project1./dc-project2 文件夹中运行docker-compose -f f1.yml -f f2.yml up -d 时,您将收到以下错误:You have to remove (or rename) that container to be able to reuse that name

  1. 当您使用被覆盖的文件时,您的 Docker 网络也会出现类似的问题: 删除了大部分自定义设置,使网络设置更清晰

网络将从docker-compose up 上的覆盖文件中正确附加,但只要你想docker-compose start,它就会查找你的默认网络名称:默认的docker-compose.yml 甚至是docker-compose.override.yml 文件(如果存在)。换句话说 - 它会忽略您的自定义 docker-compose 覆盖文件(参见下面的示例):

docker-compose.yml:

   networks:
      network_frontend:
          name: stage6-network-frontend

customfolder/docker-compose.custom.yml:

   networks:
      network_frontend:
          name: magento2.3-network-frontend

解决方案

示例

目标:让docker-compose start/stop 使用相同的 docker-compose 项目在多个设置(又名项目/网站/工具)中正常工作

假设您有以下 docker-compose 文件:

**主文件:**docker-compose.yml:

   web_server:
       image: current_timezone/full-supervisord-web-server/php7.3:1.00
       container_name: web-server-apache2
       networks:
         - network_frontend
       build:
         context: "./all-services/"
         dockerfile: ./web-server/Dockerfile.webserver.apache2
         args:
       volumes:
         - website_data:/var/www/html
       ports:
         - "8080:8080"

   networks:
     network_frontend:
       driver: bridge
       ipam:
         driver: default
         config:
           - subnet: 172.100.0.0/16
       name: stage6-network-frontend
       driver_opts:
         # Custom name for host-side network : for instance on Ubuntu : ip addr | ifconfig
  com.docker.network.bridge.name: docker-custom # Seems limit of 15 characters only

然后是覆盖文件customfolder/magento2.override.yml:

     web_server:
       container_name: web-server-apache2-magento2.3.5
       networks:
         - network_frontend
       build:
         args:
       volumes:
         - website_data:/var/www/html
       ports:
         - "8080:8080"

   networks:
     network_frontend:
       driver: bridge
       ipam:
         driver: default
         config:
           - subnet: 172.100.0.0/16
       driver_opts:
         # Custom name for host-side network : for instance on Ubuntu : ip addr | ifconfig
  com.docker.network.bridge.name: d-glo-femag2_35 # Seems limit of 15 characters only
       name: glo-magento2.3-network-frontend

执行以下操作:

  1. 完整的 Docker 项目(Dockerfiles/ADDs/docker-compose.yml 文件等)复制到一个新的单独文件夹中:

    /var/docker/project1 /var/docker/project2

  2. 确保您的 override docker-compose.yml 中的 container_name 条目在两个项目之间是唯一的。

  3. 在项目 project1 中运行 docker-compose -f docker-compose.yml -f customfolder/magento2.override.yml up -d && docker-compose stop,导航到 project2 并执行相同操作。

按照 David Maze 的建议使用 -p 标志本身并不能正常工作,JSON 文件仍以 ./foldername 的形式在 docker-compose start/stop 上获取

  1. 由于网络在 start/stop 上存在类似问题,因此在您可以正确使用覆盖文件中定义的自定义名称之前,......不幸的是,您需要更新主库docker-compose.yml 到被覆盖的文件!

扩展说明:没有办法从docker-compose start调用正确的自定义网络名称,所以由于docker-compose忽略了start上被覆盖的文件,你需要确保更新基础文件docker-compose.yml或者docker-compose.override.yml 有您的自定义网络名称。

如果您在使用up -d之前没有更新名称,则需要替换每个/var/lib/docker/containers/*/config.v2.json的内容。

例如你可以这样做:你必须先停止 docker

  sudo service docker stop
  find /var/lib/docker/containers/ -type f -name "config.v2.json" -exec sed -i "s|wrong-network-name|overridden-network-name|g" '{}' \;
  sudo service docker start
  1. 如果操作正确,您应该有唯一的容器名称,并且现在可以正确地分别访问每个文件夹而不会破坏彼此的容器:docker-compose startdocker-compose stopdocker-compose ps

注意:您仍然需要导航到单独的文件夹才能运行这些命令

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 2022-11-11
    • 2021-01-08
    • 1970-01-01
    相关资源
    最近更新 更多