我已经有一个像这样的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文件同时工作?我想知道是否可能?
我希望能够停止和更新一个环境。而另一个仍在运行并获得流量。
也许我需要其他方法吗?
答案 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覆盖不同环境的端口映射。