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