Conditionally mount volumes in docker-compose for several conditions
You can set defaults for environment variable in a .env
-file shipped alongside with a docker-compose.yml
[1].
By setting your environment variables to /dev/null
by default and then handling this case in the containerized application, you should be able to achieve what you need.
Example
$ tree -a.├── docker-compose.yml├── Dockerfile├── .env└── run.sh
docker-compose.yml
version: "3"services: test: build: . environment: - VOL_DST=${VOL_DST} volumes: - "${VOL_SRC}:${VOL_DST}"
Dockerfile
FROM alpineCOPY run.sh /run.shENTRYPOINT ["/run.sh"]
.env
VOL_SRC=/dev/nullVOL_DST=/volume
run.sh
#!/usr/bin/env shset -euo pipefailif [ ! -d ${VOL_DST} ]; then echo "${VOL_DST} not mounted"else echo "${VOL_DST} mounted"fi
Testing
Environment variable VOL_SRC
not defined:
$ docker-compose upStarting test_test_1 ... doneAttaching to test_test_1test_1 | /volume not mountedtest_test_1 exited with code 0
Environment variable VOL_SRC
defined:
$ VOL_SRC="./" docker-compose upRecreating test_test_1 ... doneAttaching to test_test_1test_1 | /volume mounted
[1] https://docs.docker.com/compose/environment-variables/#the-env-file
While @Ente's answer solves the problem, here is an alternative solution when you have more complex differences between environments.
Docker compose supports multiple docker-compose files for configuration overriding in different environments.
This is useful for instance if you have different named volumes you need to potentially mount on the same path depending on the environment.
You can modify existing services or even add new ones, for instance:
# docker-compose.ymlversion: '3.3'services: service-a: image: "image-name" volumes: - type: volume source: vprod target: /data ports: - "80:8080"volumes: vprod: vdev:
And then you have the override file to change the volume mapping:
# docker-compose.override.ymlservices: service-a: volumes: - type: volume source: vdev target: /data
When running docker-compose up -d
both configurations will be merged with the override file taking precedence.
Docker compose picks up docker-compose.yml
and docker-compose.override.yml
by default, if you have more files, or files with different names, you need to specify them in order:
docker-compose -f docker-compose.yml -f docker-compose.custon.yml -f docker-compose.dev.yml up -d