Как насчет:
cat <<EOF
version: "3"
services:
web1:
image: python:2.7-alpine
command: ["python", "-m", "SimpleHTTPServer", "8080"]
web2:
image: python:2.7-alpine
command: ["python", "-m", "SimpleHTTPServer", "8080"]
EOF
Затем получите виртуальные адреса, например, через:
docker ps | grep compose_ | cut -f1 -d' ' | while read s; do docker inspect $s | egrep "IPAddr.*[0-9]"; done
"IPAddress": "172.28.0.3",
"IPAddress": "172.28.0.2",
Затем подтвердите, что оба адреса отвечают на один и тот же порт:
$ curl -sv 172.28.0.2:8080
...
* Connected to 172.28.0.3 (172.28.0.3) port 8080 (#0)
...
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html>
...
$ curl -s 172.28.0.3:8080
...
Вы можете использовать пользовательские сети, чтобы изолировать контейнеры особым образом, но даже с поведением по умолчанию вы можете создать несколько экземпляров этого стека компоновки, и вы всегда будете получать уникальные виртуальные адреса, на которые вы можете выборочно обращаться с вашего клиента. Вы можете поставить обратный прокси-сервер впереди, если хотите направить трафик внешнего клиента в конкретный бэкэнд.
Вы можете иметь несколько экземпляров, переопределив имя проекта для каждого экземпляра с помощью $ COMPOSE_PROJECT_NAME или -p. например:
docker-compose -p mytest1 up -d
docker-compose -p mytest2 up -d
Надеюсь, это поможет.