109

Docker 1.9 allows to pass arguments to a dockerfile. See link: https://docs.docker.com/engine/reference/builder/#arg

How can I pass the same arguments within docker-compose.yml?
Please provide an example too, if possible.

Vini.g.fer
  • 11,639
  • 16
  • 61
  • 90
meallhour
  • 13,921
  • 21
  • 60
  • 117

5 Answers5

99

Now docker-compose supports variable substitution.

Compose uses the variable values from the shell environment in which docker-compose is run. For example, suppose the shell contains POSTGRES_VERSION=9.3 and you supply this configuration in your docker-compose.yml file:

db:
  image: "postgres:${POSTGRES_VERSION}"

When you run docker-compose up with this configuration, Compose looks for the POSTGRES_VERSION environment variable in the shell and substitutes its value in. For this example, Compose resolves the image to postgres:9.3 before running the configuration.

Hemerson Varela
  • 24,034
  • 16
  • 68
  • 69
  • 7
    Build arguments is a Docker 1.9 feature, the question asked how to get Docker Compose to use them. Variable substitution is unrelated. – Jack Feb 19 '16 at 05:51
  • 8
    @Jack I know this is not a direct answer to the question, but it could be a workaround since the `docker-compose` doesn't support passing arguments. – Hemerson Varela Feb 19 '16 at 14:35
  • 23
    @Jack I came here looking for variable substitution so this was helpful to me – Andy Jul 13 '16 at 20:19
  • Will be using the this for the time being. Can't use `docker-compose run` to pass in arguments as the argument has to be passed to multiple containers. – andho Feb 20 '17 at 04:27
  • Is there a way to set a default value in one place? We've been doing `${PLATFORM_VERSION:-v1.0.0}` all over and it would be nice to just put the default in one spot. – weberc2 Sep 05 '18 at 19:56
  • 3
    @weberc2 I know at this time you should have figured out but I'll leave it here for others. You can set it as an environment with a default value in your `docker-compose.yml` file. `environment:\n PLATFORM_VERSION: "${PLATFORM_VERSION:-v1.0.0}"`. PS: `\n` is just because I couldnt find a way to format multiline code block in comments. – Sidney de Moraes Mar 29 '19 at 19:02
98

This can now be done as of docker-compose v2+ as part of the build object;

docker-compose.yml

version: '2'
services:
    my_image_name:
        build:
            context: . #current dir as build context
            args:
                var1: 1
                var2: c

See the docker compose docs.

In the above example "var1" and "var2" will be sent to the build environment.

Note: any env variables (specified by using the environment block) which have the same name as args variable(s) will override that variable.

tgallacher
  • 1,594
  • 1
  • 10
  • 7
  • @tfg Do you know if the `args` keys need to be lowercase? The docs and all of the examples I've seen use lowercase keys, but I haven't seen any mention of that being _required_. – pdoherty926 Aug 31 '16 at 17:38
  • @pdoherty926 This should just be bash variable expansion, so uppercase and lowercase with underscores should be fine. – tgallacher Sep 03 '16 at 09:25
  • @tfg Thanks. I came to that conclusion myself in the meantime. Do you have any idea why the docs/examples use that convention? – pdoherty926 Sep 03 '16 at 13:20
  • 1
    Unfortunately, this doesn't work for stacks: "This option is ignored when deploying a stack in swarm mode with a (version 3) Compose file. The docker stack command accepts only pre-built images" from https://docs.docker.com/compose/compose-file/#build – joshmcode Oct 13 '17 at 20:05
  • 1
    @tgallacher AFAIK, the variables in the `environment` block don't override `args` variables. It's just that `args` variables are available during the container **build process**, but `environment` variables are available while the container is **running**. – Masood Khaari Nov 26 '18 at 15:04
62

This feature was added in Compose file format 1.6.

Reference: https://docs.docker.com/compose/compose-file/#args

services:
  web:
    build:
      context: .
      args:
        FOO: foo
dnephin
  • 25,944
  • 9
  • 55
  • 45
  • When I run `docker-compose version` it says 1.29.1 and that, as of this time of writing, is the latest. 1.6? – volvox Jul 15 '21 at 14:45
  • 1
    @volvox he was referring the `Compose file format` (Compose) , you are referring to `docker-compose`, different things. 1.6 is deprecated now. This post is quite old :) – Souza Aug 11 '21 at 17:50
5

Something to add to these answers that the args are picked up only when using docker-compose up --build and not when using docker-compose build. If you want to build and run in separate steps, you need use docker-compose build --build-arg YOUR_ENV_VAR=${YOUR_ENV_VAR}or docker build --build-arg YOUR_ENV_VAR=${YOUR_ENV_VAR}

AndyFaizan
  • 1,833
  • 21
  • 30
  • Not sure if something changed but I've just built with `docker-compose build` and the build took my variables on the docker-compose.yml file just fine. No need to use --build-arg. – M. Gleria Aug 01 '22 at 17:49
  • 1
    `docker compose build --build-arg USERNAME=xxx` did not work for me. It says `WARN[0000] The "USERNAME" variable is not set. Defaulting to a blank string.` – igor Aug 05 '22 at 08:08
  • @M.Gleria: perhaps the api is updated now – AndyFaizan Aug 05 '22 at 13:27
  • 1
    @igor: Its possible the apis for `docker-compose` and `docker compose` are different (the latter was introduced later) – AndyFaizan Aug 05 '22 at 13:28
4
  1. Create a variable environment on Linux shell:

    export TAG=0.1.2
    
  2. Set variable inside docker-compose.yml

    db:
      image: "redis:${TAG}"
    
  3. Verify if value was replaced

    docker-compose config