Docker Compose, как писали в комментариях, решает проблему запуска всего этого в определённой конфигурации на одной машине.
В продакшене у Вас будет несколько машин. MongoDB, вероятно, будет отдельно. Можно использовать Docker Swarm или Kubernetes. На вкус и цвет. Для Сворма конфг очень похож на конфиг для Docker Compose, только значения, специфичные для окружения, будут другими. Kubernetes тоже конфигурируется YAML или JSON описаниями разнообразных сущностей. Если есть Kubernetes-как-сервис - берите, не пожалеете. А можно вообще обойтись конфигурациями SystemD, которые будут запускать нужные контейнеры. Тогда всё это можно будет описать в unit-файлах SystemD и положить в правильные папочки на Линуксе.
С версионированием всё просто.
Во-первых, нужно определиться с репозиторием Докер-образов. Можно и свой развернуть из доступных вариантов (и родной Docker Registry, и Atomic Registry, и Nexus, и GitLab - это всё Open Source). А можно воспользоваться сервисами Docker Hub, Google Container Registry, Quay.io или Amazon.
Во-вторых, после очередного коммита можно с помощью CI-движка собирать новый образ, присваивать ему тег с очередным номером версии, а в лейблы записывать, из какого коммита он собран.
Дальше достаточно поправить декларативное описание вашего окружения - там фигурируют образы с тегами. И - вот она, новая версия. И новый файл для Docker Compose.
Резюме: с Докером эту проблему решить гораздо проще, чем как-либо иначе. То есть, можно с таким же успехом упаковать всё это в несколько полновесных виртуалок, но память имеет свойство заканчиваться.