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

时间:2019-04-05 10:32:48

标签: 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
  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

我的目标是让2个隔离环境在同一服务器上使用相同的docker-compose文件同时工作?我想知道是否可能?

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

也许我需要其他方法吗?

2 个答案:

答案 0 :(得分:1)

您要执行的操作有几个问题。如果您的目标是将事情放到负载均衡器后面,我认为与其尝试启动项目的多个实例,不如尝试更好的解决方案,是使用可用于docker-compose的缩放功能。尤其是,如果您的目标是将某些服务放在负载均衡器的后面,则可能不需要多个实例,例如数据库。

如果将其与Traefik之类的动态前端代理结合使用,则可以使配置在很大程度上是自动的。

考虑一个非常简单的示例,该示例由运行简单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

但是我也可以要求docker-compose扩展后端:

docker-compose up --scale webserver=3

在这种情况下,我只有一个前端服务器和三个后端服务器。 Traefik将自动发现后端,并在它们之间进行循环连接。您可以下载this example并尝试一下。

注意事项

为了使这项工作有效,您需要更改配置的某些方面(实际上,即使您要按照项目中的建议创建项目的多个实例,也需要更改它们。问题)。

路径冲突

webserver容器的配置为例:

volumes:
    - ./logs:/var/log/nginx:delegated

如果启动此服务的两个实例,则两个容器都将./logs装载到/var/log/nginx上。如果他们俩都试图写到/var/log/nginx/access.log,那么您将遇到问题。

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

硬编码容器名称

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

mysql:
  image: mysql:5.7.21
  container_name: dl-mysql

如果您尝试启动该项目的多个实例或mysql容器的多个实例,这将导致问题。请勿静态设置容器名称。

不赞成使用的链接语法

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

links:
  - mysql

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

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"

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

答案 1 :(得分:0)

如果不更改端口映射,将无法在主机上运行相同的撰写文件,因为这将导致端口冲突。我建议创建一个基本的撰写文件,并使用extends覆盖不同环境的端口映射。