Docker-Compose bind volume only if exists

Viewed 1660

I have a volume which uses bind to share a local directory. Sometimes this directory doesn't exist and everything goes to shit. How can I tell docker-compose to look for the directory and use it if it exists or to continue without said volume if errors?

Volume example:

  - type: bind
    read_only: true
    source: /srv/share/
    target: /srv/share/
1 Answers

How can I tell docker-compose to look for the directory and use it if it exists or to continue without said volume if errors?

As far I am aware you can't do conditional logic to mount a volume, but i am getting around it in a project of mine, like this:

version: "2.1"

services:

  elixir:
    image: elixir:alpine
    volumes:
      - ${VOLUME_SOURCE:-/dev/null}:${VOLUME_TARGET:-/.devnull}:ro

Here I am using /dev/null as the fallback, but in my real project I just use an empty file to do the mapping.

This ${VOLUME_SOURCE:-/dev/null} is how bash works with default values for variables not set, and docker compose supports them.

Testing it without setting the env vars

$ sudo docker-compose run --rm elixir sh 

/ # ls -al /.devnull 
crw-rw-rw-    1 root     root        1,   3 May 21 12:27 /.devnull

Testing it with the env vars set

Creating the .env file:

$ printf "VOLUME_SOURCE=./testing \nVOLUME_TARGET=/testing\n" > .env && cat .env
VOLUME_SOURCE=./testing 
VOLUME_TARGET=/testing

Creating the volume for test purposes:

$ mkdir testing && touch testing/test.txt && ls -al testing
total 8
drwxr-xr-x 2 exadra37 exadra37 4096 May 22 13:12 .
drwxr-xr-x 3 exadra37 exadra37 4096 May 22 13:12 ..
-rw-r--r-- 1 exadra37 exadra37    0 May 22 13:12 test.txt

Running the container:

$ sudo docker-compose run --rm elixir sh
/ # ls -al /testing/
total 8
drwxr-xr-x    2 1000     1000          4096 May 22 12:01 .
drwxr-xr-x    1 root     root          4096 May 22 12:07 ..
-rw-r--r--    1 1000     1000             0 May 22 12:01 test.txt
/ # 
Related