Conditionally mount volumes in docker-compose for several conditions Conditionally mount volumes in docker-compose for several conditions docker docker

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