Using environment variable for volume name in docker compose

If you want to avoid conflicts between different projects, you just need to specify --project-name "your_project_name" for docker-compose. It adds namespace for all services and volumes.

For example, you may use the same docker-compose.yml for few projects:

volumes:
    dbdata_mysql:

services:
    mysql_db:
        image: mysql:5.7
        volumes:
            - "dbdata_mysql:/var/lib/mysql"

If you starts your projects with:

docker-compose --project-name "first_project" up -d
docker-compose --project-name "second_project" up -d

it will create namespaced volumes:

$ docker volume ls | grep dbdata_mysql

local     first_project_dbdata_mysql
local     second_project_dbdata_mysql

If you need to change complex stuff between environments, like using completely different volume settings, you should override your configuration with multiple docker-compose files.

Environment variables should be used for simple values only.

Using multiple configuration files lets you define a default docker-compose.yml file with your base configuration, and another docker-compose.override.yml for the changes you need for a particular environment.

Then, when creating the services, docker compose will merge the configuration files.

In your case, your default configuration might look like this:

# docker-compose.yml
version: '3.3'
services:
  target:
    image: "my-registry/my-image:${IMAGE_TAG}"
    volumes:
        - type: volume
          source: vprod
          target: /data
    ports:
     - "80:8080"

volumes:
  vprod:

And your dev override file may look like this:

# docker-compose.override.yml
services:
  target:
    volumes:
        - source: vdev
          target: /data
    ports:
     - "8080:8080"

volumes:
  vdev:

Notice that not all services and not all keys need to be repeated in the override file.

When you run docker-compose up 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

This is expected behavior - Compose only does variable interpolation in values, not keys. See here.

In my project I use external structure:

version: '3.1'
services:
### Code from branch develop ###
  applications:
    image: registry.gitlab.lc:5000/develop/ed/develop.sources:latest
    volumes:
      - developcode:/var/www/develop
    deploy:
      replicas: 1
      update_config:
        parallelism: 1
        delay: 5s
      restart_policy:
        condition: on-failure
      placement:
        constraints: [node.role == manager]
### PHP-FPM ###
  php-fpm:
    image: registry.gitlab.lc:5000/develop/ed/php-fpm-ed-sq:latest
    volumes:
      - developcode:/var/www/develop
    expose:
      - "9000"
    deploy:
      replicas: 2
      update_config:
        parallelism: 1
        delay: 5s
      restart_policy:
        condition: on-failure
      placement:
        constraints: [node.role == manager]
    logging:
      driver: gelf
      options:
        gelf-address: "udp://${GRAYLOG_ADDR}:12201"
        tag: "php-fpm"
### Nginx ###
  nginx:
    image: registry.gitlab.lc:5000/develop/ed/nginx-ed-sq:staging
    volumes:
      - developcode:/var/www/develop
    ports:
      - "80:80"
      - "443:443"
    deploy:
      replicas: 2
      update_config:
        parallelism: 1
        delay: 5s
      restart_policy:
        condition: on-failure
      placement:
        constraints: [node.role == manager]
### Volumes Setup ###
volumes:
  developcode:
    external:
      name: code-${VER}

but first of all I need create external volume manually, e. g.:

export VER=1.1 && docker volume create --name code-$VER

You can see created volume:

docker volume ls
DRIVER              VOLUME NAME
local               code-1.0
local               code-1.1

And after that, deploy services using:

env $(cat .env | grep ^[A-Z] | xargs) docker stack deploy --with-registry-auth --compose-file docker-compose.yml MY_STACK