142

In my docker compose file there is a dynamic field which I'd like to generate during the running. Actually it is a string template:

environment:
    - SERVER_URL:https://0.0.0.0:${PORT}

And I want to configure this PORT parameter dynamically

docker-compose run <service> PORT=443

In documentation there is ARGS parameters set I suppose I can use. But there is no information how can I use those inside compose file

7

9 Answers 9

72

In docker-compose, arguments are available and usefull only in dockerfile. You can specify what you are doing in the level ahead like following:

#dockerfile
ARG PORT
ENV SERVER_URL "https://0.0.0.0:$PORT"

Your port can be set in your docker-compose.yml:

build:
  context: .
  args:
    - PORT=443

It is actually an environment variable in any case. You can pass it through your run command if that fits to you:

PORT=443 docker-compose run <service>
#or
docker-compose run <service> -e PORT=443
Sign up to request clarification or add additional context in comments.

6 Comments

This sucks, I want to be able to download a pre-built container and run it with whatever runtime arguments I choose. Being able to list them in docker-compose should be basic functionality. I'll just override the entrypoint.
@Dagrooms I think this is possible with stack deploy. See my answer.
This worked for me and I did not have to touch my Dockerfile. I used PORT=443 docker-compose ... -f bla.yml to pass the port in and then in my YAML file, the line command: bash -c "echo $PORT" successfully displayed 443.
This does not seem to work anymore, unfortunately. - When using MYARG=123 docker-compose run <service>, it returns "The terum MYARG=12345 is not recognized as a cmdlet name, function, script file or operating program." - When using docker-compose run <service> -e MYARG=123, it returns "Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-e": executable file not found in $PATH: unknown"
The answer by @mareoraft worked perfectly and is the cleanest option imo. I think it should be turned into an actual answer so it doesn't get easily overlooked!
|
63

You can use the flag when using docker-compose build

docker-compose build --build-arg PRODUCTION=VALUE

In Dockerfile you can get the argument PRODUCTION

# Dockerfile
ARG PRODUCTION
FROM node:latest

1 Comment

Not exactly what was asked originally, but you helped me a lot for the build stage.
13

This is possible with docker stack deploy

Example Compose File in your environment section:

- MY_VARIABLE_NAME=${MY_VARIABLE_VALUE}

Stack Deploy Command (I ran this from Gitbash in Windows):

MY_VARIABLE_VALUE=some-value docker stack deploy --compose-file compose_file_here stackname

Reference See this Github post here

2 Comments

Worth noting that this works with docker compose up as well
All of these answers boil down to environment variables. Too bad one can't pass an argument to docker-compose up in such a way that the variable would be expanded when "executing" the docker compose, but would NOT be seen by the container. For example, a variable that specifies which version of the image to use to spin up a particular service.
8

Sharing the only way I managed to set a runtime variable with Docker Compose using minimum setup and command changes.

On docker-compose.yml:

services:
  my_service:
    ...
    environment:
      - MYENVVAR=placeholder_value

On the terminal:

docker-compose run -e MYENVVAR=actual_value my_service

Please pay attention that the "-e" portion of the command line argument must come before the service name.

This is described on the official documentation: Set environment variables with docker compose run

1 Comment

Great answer. $ docker-compose up -e MYENVVAR=actual_value my_service doesn't work.
5

This worked for me and I did not have to touch my Dockerfile:

I used

PORT=443 docker-compose ...(whatever)... -f bla.yml

to pass the port in and then in my YAML file, the line command: bash -c "echo $PORT" successfully displayed 443.

Comments

5

We can pass the argument to docker compose like that: Run the docker-compose.yaml with this command:

$ ENV=staging docker-compose up

docker-compose.yaml file look like that:

...
go:
    container_name: mailavail_go
    build:
      context: ./go
      dockerfile: Dockerfile
      args:
        ENV: ${ENV} # we can defined arguments like that
    ports:
      - 8080:8080
...

Dockerfile file look like that:

...
FROM golang:latest

ARG ENV=dev # we can also add a default value

ENV ENV=${ENV} # this will set the value

echo "My ENV is ${ENV}" # This is for testing purpose and it will the ENV value

RUN mkdir /golang
...

Comments

1

This is possible with docker-compose with ARGS inside Dockerfile.

Problem to Solve:

  • Pull changes from Git Respository, to Automate App Deploy

Dockerfile

RUN 
ARG CACHEBUST=1 # This will setup a arg called CACHEBUST
RUN  git clone

Run the below bash command to build and run. SETTING --build-arg CACHEBUST= random md5sum hash, makes Docker-Compose to rebuild the image, starting the line with ARGS and so on.

docker-compose -f dockerprd.yml build  --build-arg CACHEBUST=$(echo $RANDOM | md5sum | head -c 20; echo;) && docker-compose -f dockerprd.yml up -d

Comments

1

To use variables in a docker-compose.yml or compose.yml file you can do this:

  1. Reference the variable in the file docker-compose.yml:
# docker-compose.yml
version: '3.8'

name: "my_project"
services:
  db:
    image: postgres:$docker_image_version # <- this is the variable
    restart: always
    environment:
      POSTGRES_PASSWORD: example
  1. Define a .env file in the same directory as docker-compose.yml:
# .env
docker_image_version="16-alpine3.19"
  1. Check that the variables are correctly replaced:
docker compose config

You should see that the variable will be replaced:

name: my_project
services:
  db:
    environment:
      POSTGRES_PASSWORD: example
    image: postgres:16-alpine3.19
    networks:
      default: null
    restart: always
networks:
  default:
    name: my_project_default
  1. Start the containers;
docker compose up -d
  1. Check the running containers:
docker compose ps

You should see something like:

NAME              IMAGE                    COMMAND                           SERVICE   CREATED         STATUS         PORTS
my_project-db-1   postgres:16-alpine3.19   "docker-entrypoint.sh postgres"   db        5 seconds ago   Up 5 seconds   5432/tcp

In the output you can see that it is running the version set in the .env file: 16-alpine3.19

Source: Docker compose documentation

Comments

0

The solution that I found for this problem was to dynamically create an env file and pass it as --env-file value.

I created a bash script:

$PROJ=$1
echo "REST_URL=http://$2" > ./docker-env-$PROJ
echo "BRANCH=$3" >> ./docker-env-$PROJ

docker compose \
      -p $PROJ \
      --env-file ./docker-env-$PROJ \
      up -d

rm -f ./docker-env-$PROJ

and run it:

start_all.sh mycont "localhost:8080" master

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.