Can you use the current project_name in a docker compose file?

Viewed 1068

I see lots of questions around setting/changing the COMPOSE_PROJECT_NAME or PROJECT_NAME using ENV variables.

I'm fine with the default project name, but I would like to reference it in my compose file.

version: "3.7"
services:
  app:
    build: DockerFile
    container_name: app
    volumes:
      - ./:/var/app
    networks:
      - the-net

  npm:
    image: ${project_name}_app
    volumes:
      - ./:/var/app
    depends_on:
      - app
    entrypoint: [ 'npm' ]
    networks:
     - the-net

npm here is arbitrary , hopefully the fact that could be run as its own container or in other ways does not distract from the questions.

is it possible to reference the project name with out setting it manually or first?

2 Answers

Unfortunately it is not possible.

As alluded to, you can create a .env file and populate it with COMPOSE_PROJECT_NAME=my_name, but the config option does not present itself in your environment by default.

Unfortunately the env substitution in docker-compose is fairly limited, meaning we cannot use the available PWD env variable and greedy match it at all

$ cd ~
$ pwd
/home/tqid
$ echo "Base Dir: ${PWD##*/}"
Base Dir: tqid

When we use this reference, compose has issues:

$ docker-compose up -d
ERROR: Invalid interpolation format for "image" option in service "demo": "${PWD##*/}"

It's probably better to be explicit anyway, the COMPOSE_PROJECT_NAME is based on your dir, and if someone clones to a new folder then it gets out of whack, including the .env file in source control would provide a re-usable and consistent place to reference the name

https://docs.docker.com/compose/reference/envvars/#compose_project_name

using the same image as another container was what I was after ... reuse the image and change the entry point.

Specify the same build: options for both containers.

This seems inefficient, in that it will trigger the build sequence twice and docker images will list both of them. However, the way Docker's layer caching works, if identical RUN commands are run on identical input images, the resulting layer will simply be reused, and the two final images will have the same image ID; they will literally be the same image with two names.

The context I've run into this the most is with a Python application where the same code base is used for a Django or Flask Web server, plus a Celery worker. The Docker-level setup is fairly language-independent, though: specify the same build: for both containers, and override the command: for the container(s) that need to do a non-default task.

version: '3.8'
services:
  app:
    build: .
    ports: ['3000:3000']
    environment:
      REDIS_HOST: redis
  worker:
    build: .                 # <-- same as app
    command: npm run worker  # <-- overrides Dockerfile CMD
    environment:
      REDIS_HOST: redis
  redis:
    image: redis

It is also valid to specify build: and image: together in the docker-compose.yml file; this specifies the name of the image that will be built. It's frequently useful to explicitly specify this because you will need to point at a specific Docker Hub or other registry location to push the built image. If you do this, then you'll know the image name and don't need to depend on the context name.

version: '3.8'
services:
  app:
    build: .
    image: registry.example.com/my/app:${TAG:-latest}
  worker:
    image: registry.example.com/my/app:${TAG:-latest}
    command: npm run worker

You will need to manually docker-compose build in this setup. Compose's workflow doesn't have a way to specify that one container's build must run before a different container can start.

Related