CvRChameleon
CvRChameleon

Reputation: 421

Access container_name in Dockerfile (from docker-compose)

I have setup a docker-compose project which are creating multiple images:

cache_server:
    image: current_timezone/full-supervisord-cache-server:1.00
    container_name: renamed-varnish-cache
    networks:
      - network_frontend
    build:
      context: "./all-services/"
      dockerfile: "./cache-server/Dockerfile.cacheserver.varnish"
      args:
        - DOCKER_CONTAINER_USERNAME=username
    ports:
      - "6081:6081"
      - "6082:6082"

When I use docker-compose up -f file1.yml file2.override.yml I will then get the containers: in the case of above one it will be named : renamed-varnish-cache

In the corresponding Dockerfile (./nginx-proxy/Dockerfile.proxy.nginx) I want to be able use the container_name property defined in the docker-compose.yml shown above.

When the containers are created I want to update the Varnish configurations inline inside Dockerfile : RUN sed -i "s|webserver_container_name|renamed-varnish-cache|g" /etc/varnish/default.vcl"

For instance:

    backend webserver_container_name{
        .host = "webserver_container_name";
        .port = "8080";
    }

To: I anticipate I will have to replace the - with _ for the backend:

    backend renamed_varnish_cache{
        .host = "renamed-varnish-cache";
        .port = "8080";
    }

Is there a way to receive the docker-compose named items as variables inside Dockerfile?

Upvotes: 1

Views: 1251

Answers (1)

David Maze
David Maze

Reputation: 159830

In core Docker, there are two separate concepts. An image is a built version of some piece of software packaged together with its dependencies; a container is a running instance of an image. There are separate docker build and docker run commands to build images and launch containers, and you can launch multiple containers from a single image.

Docker Compose wraps these concepts. In particular, the build: block corresponds to the image-build step, and that is what invokes the Dockerfile. None of the other Compose options are available or visible inside the Dockerfile. You cannot access the container_name: or environment: variables or volumes: because those don't exist at this point in the build lifecycle; you also cannot contact other Compose services from inside the Dockerfile.

It's pretty common to have multiple containers run off the same image if they have largely the same code base but need a different top-level command. One example is a Python Django application that needs Celery background workers; you'd have the same project structure but a different command for the Celery worker.

version: '3.8'
services:
  web:
    build: .
    image: my/django-app
  worker:
    image: my/django-app
    command: celery worker ...

Now with this stack you can docker-compose build to build the one image, and then run docker-compose up to launch both containers from that image. (During the build you can't know what the container names will be, and there will be two container names so you can't just use one in the Dockerfile.)

At a design level, this means that you often can't include configuration-type settings in the image itself (other containers' hostnames, user IDs for host-shared filesystems). If your application lets you specify these things as environment variables, that's the easiest option. You can use bind mounts (volumes:) to inject whole config files. If neither of these things work for you, you can use an entrypoint script to rewrite the config file.

Upvotes: 2

Related Questions