206

I have the following docker-compose file

version: '3'
services:
    node1:
            build: node1
            image: node1
            container_name: node1

    node2:
            build: node2
            image: node2
            container_name: node2

I can build both images and start them with a single command

docker-compose up -d --build

But I would like to use build-args on the builds. The original build script of the image outside of the scope of compose looks something like this

#!/bin/sh
docker build \
--build-arg ADMIN_USERNNAME_1=weblogic \
--build-arg ADMIN_PASSWORD_1=weblogic1 \
--build-arg ADMIN_NAME_1=admin \
--build-arg ...
--build-arg ... \
-t test/foo .

Both images would use build-args of the same name but different value. Also, as there are dozens of build args, it would be convenient to store them in a compose service specific build-properties file. Is this possible with docker-compose?

3
  • 11
    Warning for later people: for passwords, you might consider using a secret manager (Vault, k8s secrets, aws sms, docker swarm secrets) instead of a build arg to avoid security breaches. A build-time arg will bake the cred in the image, which means anyone with pull access can read it. Avoid using credentials at build-time. Commented Dec 25, 2020 at 20:02
  • 2
    Very important note about security, thanks a lot. Here is a solution: pythonspeed.com/articles/build-secrets-docker-compose Commented May 19, 2021 at 9:35
  • @Bira I fail to see what this question has to do with AWS. The question doesn't mention it, and docker-compose is indeed an independent product. Commented Apr 24, 2023 at 7:05

5 Answers 5

218

You can specify the arguments directly in your docker-compose file:

node1:
    build:
        context: node1
        args:
            ADMIN_USERNNAME: weblogic1
            ADMIN_PASSWORD: weblogic1
            ADMIN_NAME: admin1
    image: node1
    container_name: node1

See a full example: MWE

The official docs (legacy v3 here) have all detail.

Sign up to request clarification or add additional context in comments.

5 Comments

For some reason args in the docker-compose file did not work for me when trying to use a shell var. Instead I had to use --build-arg VARNAME=$VARNAME when running the command.
@harvzor Not sure what you mean by that. Do you expect docker-compose to have excess to a Bash variable outside of its own runtime? Yeah, that won't work, and it shouldn't. You can use environment variables, though: docs.docker.com/compose/environment-variables
For multiline --build-arg, see stackoverflow.com/a/67135826/432903
How can I do it without editing the compose file? I need to make the container use a proxy, but I don't want to change the config for anyone else on the team
63

You can define your args with your build command of docker-compose.

Example Dockerfile:

FROM nginx:1.13

RUN apt-get -y update && apt-get install -y \
    apache2-utils && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

ARG username
ARG password

RUN htpasswd -bc /etc/nginx/.htpasswd $username $password

docker-compose file:

version: '3'
services:
  node1:
     build: ./dir

The ./dir contains the Dockerfile and I build with this command:

docker-compose build --build-arg username="my-user" --build-arg password="my-pass"

I see already:

Step 5/5 : RUN htpasswd -bc /etc/nginx/.htpasswd $username $password
 ---> Running in 80735195e35d
Adding password for user my-user
 ---> c52c92556825

I bring my stack up:

docker-compose up -d

Now I can check inside the nginx container and my username and (encrypted) password are there:

docker@default:~/test$ docker exec -it test_node1_1 bash
root@208e4d75e2bd:/# cat /etc/nginx/.htpasswd
my-user:$apr1$qg4I/5RO$KMaOPvjbnKdZH37z2WYfe1

Using this method your able to pass build args to your docker-compose stack.

4 Comments

Environment variables can be used as you said, but they have to be defined in .env, not inside the compose file
This answer is very useful, it actually shows how docker-compose can be used with --build-arg on command-line, you can define your ARG in Dockerfile, docker-compose.yml - the :args array defined and then finally override it on the command-line.
Seems correct, but for others, be wary of baking credentials into images like this. Username/password should be done at runtime, so your prod credentials don't show up in your repository
This is the answer I was looking for, showing that --build-arg can be used with docker-compose
48

In your Dockerfile:

ARG CERTBOT_TAG=latest
FROM certbot/certbot:${CERTBOT_TAG}

In your docker-compose.yml file:

version: '3.4'
services:
  certbot:
    build:
      context: .
      args:
        CERTBOT_TAG: v0.40.1

And you can build or up your service:

docker-compose build certbot

2 Comments

I got an error using this format, ERROR: The Compose file './docker-compose.yml' is invalid because: services.certbot.build.args contains {"CERTBOT_TAG": "v0.40.1"}, which is an invalid type, it should be a string My solution was to remove the - to turn it into a string instead of an object.
@heralight please fix the YAML syntax!
7

As Salek mentioned above, adding context: . helps.

For example:

version: '3.5'
services:
  app:
    build:
      context: .
      args:
        NODE_VERSION: 14.15.4
       

`

Comments

4

Docker File

ARG ACCOUNT_ID

FROM $ACCOUNT_ID.dkr.ecr.ap-southeast-1.amazonaws.com/my-composer:latest as composer
LABEL stage=intermediate

Buildspec or CLI execute the following command.

docker-compose build --build-arg ACCOUNT_ID="23423432423" --no-cache

If you want to print the ACCOUNT_ID in CLI

ARG ACCOUNT_ID

FROM amazonlinux:latest
RUN yum -y install aws-cli 
RUN echo $ACCOUNT_ID

FROM $ACCOUNT_ID.dkr.ecr.ap-southeast-1.amazonaws.com/my-composer:latest as composer
LABEL stage=intermediate

Note: ARG should be on top of all FROM statement, then it will work as global ARG.

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.