如何使用相同的docker-compose.yml文件创建两个不同的运行应用程序?

如何使用相同的docker-compose.yml文件创建两个不同的运行应用程序?,docker,docker-compose,containers,devops,Docker,Docker Compose,Containers,Devops,我已经有一个docker-compose.yml文件,如下所示: version: "3.1" services: memcached: image: memcached:alpine container_name: dl-memcached redis: image: redis:alpine container_name: dl-redis mysql: image: mysql:5.7.21 container_name: dl-mysql restar

我已经有一个docker-compose.yml文件,如下所示:

version: "3.1"

services:

memcached:
  image: memcached:alpine
  container_name: dl-memcached

redis:
  image: redis:alpine
  container_name: dl-redis

mysql:
  image: mysql:5.7.21
  container_name: dl-mysql
  restart: unless-stopped
  working_dir: /application
  environment:
    - MYSQL_DATABASE=dldl
    - MYSQL_USER=docker
    - MYSQL_PASSWORD=docker
    - MYSQL_ROOT_PASSWORD=docker
  volumes:
    - ./../:/application
  ports:
    - "8007:3306"

phpmyadmin:
  image: phpmyadmin/phpmyadmin
  container_name: dl-phpmyadmin
  environment:
    - PMA_ARBITRARY=1
    - PMA_HOST=dl-mysql
    - PMA_PORT=3306
    - MYSQL_USER=docker
    - MYSQL_PASSWORD=docker
    - MYSQL_ROOT_PASSWORD=docker
  restart: always
  ports:
    - 8002:80
  volumes:
    - /application
  links:
    - mysql

elasticsearch:
  build: phpdocker/elasticsearch
  container_name: dl-es
  volumes:
    - ./phpdocker/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
  ports:
    - "8003:9200"

webserver:
  image: nginx:alpine
  container_name: dl-webserver
  working_dir: /application
  volumes:
      - ./../:/application:delegated
      - ./phpdocker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
      - ./logs:/var/log/nginx:delegated
  ports:
   - "9003:80"

php-fpm:
  build: phpdocker/php-fpm
  container_name: dl-php-fpm
  working_dir: /application
  volumes:
    - ./../:/application:delegated
    - ./phpdocker/php-fpm/php-ini-overrides.ini:/etc/php/7.2/fpm/conf.d/99-overrides.ini
    - ./../docker/php-fpm/certs/store_stock/:/usr/local/share/ca-certificates/
    - ./logs:/var/log:delegated # nginx logs
    - /application/var/cache 
  environment:
    XDEBUG_CONFIG: remote_host=host.docker.internal
    PHP_IDE_CONFIG: "serverName=dl"

node:
  build:
    dockerfile: dl/phpdocker/node/Dockerfile
    context: ./../
  container_name: dl-node
  working_dir: /application
  ports:
    - "8008:3000"
  volumes:
    - ./../:/application:cached
  tty: true
mysql:
  image: mysql:5.7.21
  container_name: dl-mysql
我的目标是让两个独立的环境同时在同一台服务器上使用同一个docker compose文件工作?我想知道这是否可能

我想能够停止和更新一个环境。而另一个仍在运行并获得流量


也许我需要另一种方法?如果不更改端口映射,您将无法在主机上运行相同的compose文件,因为这将导致端口冲突。我建议您创建一个基本的compose文件,并使用它覆盖不同环境的端口映射。

您尝试执行的操作有几个问题。如果您的目标是使用负载平衡器,我认为与其尝试启动项目的多个实例,不如使用docker compose可用的缩放功能。特别是,如果您的目标是将某些服务置于负载平衡器之后,那么您可能不需要数据库之类的多个实例

如果将其与动态前端代理(如)相结合,可以使配置在很大程度上自动化

考虑一个非常简单的示例,其中包含一个运行简单Web服务器的后端容器和一个traefik前端:

---
version: "3"

services:

  webserver:
    build:
      context: web
    labels:
      traefik.enable: true
      traefik.port: 80
      traefik.frontend.rule: "PathPrefix:/"

  frontend:
    image: traefik
    command:
      - --api
      - --docker
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    ports:
      - "80:80"
      - "127.0.0.1:8080:8080"
docker-compose up
如果我这样开始,我会得到一个后端和一个前端:

---
version: "3"

services:

  webserver:
    build:
      context: web
    labels:
      traefik.enable: true
      traefik.port: 80
      traefik.frontend.rule: "PathPrefix:/"

  frontend:
    image: traefik
    command:
      - --api
      - --docker
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    ports:
      - "80:80"
      - "127.0.0.1:8080:8080"
docker-compose up
但我也可以要求docker compose扩展后端:

docker-compose up --scale webserver=3
在这种情况下,我得到一个前端和三个后端服务器。Traefik将自动发现后端,并在它们之间循环连接。您可以下载并试用

警告 您的配置有几个方面需要更改才能使其正常工作(事实上,即使您要创建项目的多个实例,您也需要更改它们,正如您在问题中所建议的那样)

冲突路径 以
webserver
容器的配置为例:

volumes:
    - ./logs:/var/log/nginx:delegated
如果启动此服务的两个实例,则两个容器都将在
/var/log/nginx
上装载
/logs
。如果它们都试图写入
/var/log/nginx/access.log
,您将遇到问题

这里最简单的解决方案是避免为日志目录(以及您将要写入的任何其他目录)绑定挂载,而是使用命名的docker卷

硬编码容器名称 在某些地方,您正在硬编码容器名称,如下所示:

version: "3.1"

services:

memcached:
  image: memcached:alpine
  container_name: dl-memcached

redis:
  image: redis:alpine
  container_name: dl-redis

mysql:
  image: mysql:5.7.21
  container_name: dl-mysql
  restart: unless-stopped
  working_dir: /application
  environment:
    - MYSQL_DATABASE=dldl
    - MYSQL_USER=docker
    - MYSQL_PASSWORD=docker
    - MYSQL_ROOT_PASSWORD=docker
  volumes:
    - ./../:/application
  ports:
    - "8007:3306"

phpmyadmin:
  image: phpmyadmin/phpmyadmin
  container_name: dl-phpmyadmin
  environment:
    - PMA_ARBITRARY=1
    - PMA_HOST=dl-mysql
    - PMA_PORT=3306
    - MYSQL_USER=docker
    - MYSQL_PASSWORD=docker
    - MYSQL_ROOT_PASSWORD=docker
  restart: always
  ports:
    - 8002:80
  volumes:
    - /application
  links:
    - mysql

elasticsearch:
  build: phpdocker/elasticsearch
  container_name: dl-es
  volumes:
    - ./phpdocker/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
  ports:
    - "8003:9200"

webserver:
  image: nginx:alpine
  container_name: dl-webserver
  working_dir: /application
  volumes:
      - ./../:/application:delegated
      - ./phpdocker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
      - ./logs:/var/log/nginx:delegated
  ports:
   - "9003:80"

php-fpm:
  build: phpdocker/php-fpm
  container_name: dl-php-fpm
  working_dir: /application
  volumes:
    - ./../:/application:delegated
    - ./phpdocker/php-fpm/php-ini-overrides.ini:/etc/php/7.2/fpm/conf.d/99-overrides.ini
    - ./../docker/php-fpm/certs/store_stock/:/usr/local/share/ca-certificates/
    - ./logs:/var/log:delegated # nginx logs
    - /application/var/cache 
  environment:
    XDEBUG_CONFIG: remote_host=host.docker.internal
    PHP_IDE_CONFIG: "serverName=dl"

node:
  build:
    dockerfile: dl/phpdocker/node/Dockerfile
    context: ./../
  container_name: dl-node
  working_dir: /application
  ports:
    - "8008:3000"
  volumes:
    - ./../:/application:cached
  tty: true
mysql:
  image: mysql:5.7.21
  container_name: dl-mysql
如果您试图启动此项目的多个实例或mysql容器的多个实例,这将导致问题。不要静态设置容器名称

不推荐的链接语法 您的配置正在使用不推荐的
链接
语法:

links:
  - mysql
不要那样做。在现代docker中,同一网络上的容器可以简单地通过名称相互引用。换句话说,如果您的compose配置具有:

mysql:
  image: mysql:5.7.21
  restart: unless-stopped
  working_dir: /application
  environment:
    - MYSQL_DATABASE=dldl
    - MYSQL_USER=docker
    - MYSQL_PASSWORD=docker
    - MYSQL_ROOT_PASSWORD=docker
  volumes:
    - ./../:/application
  ports:
    - "8007:3306"

compose堆栈中的其他容器可以简单地使用主机名
mysql
来引用此服务。

非常感谢@larsks提供了大量详细的解释,实际上我关心的一个问题是如何在不停机的情况下更新容器,所以我说了负载平衡,我想更新容器,当更新完成后,只需将流量发送到新容器。如果你真的想要零停机更新,你需要进行调查,其中包括执行更新的选项。使用legacy
docker compose
我认为总会有一个没有后端运行的简短窗口。您可以通过将内容拆分为三个项目(1个前端项目和2个后端项目)来解决此问题,这将允许单独更新每个后端项目,但这变得越来越复杂。我一直在寻找,但对于我的需求来说,这可能有些过分,但我仍然不知道如何在同一台服务器上隔离具有相同docker compose文件的两个环境:(谢谢@mukesh,有趣的事情,我稍后会尝试。我在larsks的回复中添加了一条注释,这就是我正在尝试做的