Kumar
Kumar

Reputation: 51

Store docker command result in varaible in Makefile

We are trying to store the container names in my Makefile but I see below error when executing the build, someone please advise. Thanks.

   .PHONY: metadata
metadata: .env1 
  docker pull IMAGE_NAME
  docker run  $IMAGE_NAME;
  ID:= $(shell docker ps --format '{{.Names}}')
  @echo ${ID}
  docker cp ${ID}:/app/.env .env2
  

Container names are not shown in below "ID" Variable when executing the makefile from Jenkins

ID:= 
/bin/sh: ID:=: command not found

Upvotes: 1

Views: 1214

Answers (1)

David Maze
David Maze

Reputation: 159352

There are a couple of things you can do in terms of pure Docker mechanics to simplify this.

You can specify an alternate command when you docker run an image: anything after the image name is taken as the image to run. For instance, you can cat the file as the main container command, and replace everything you have above as:

.PHONY: getmetadata
getmetadata: .env2
.env2: .env1
        docker run --rm \
          -e "ARTIFACTORY_USER=${ARTIFACTORY_CREDENTIALS_USR}" \
          -e "ARTIFACTORY_PASSWORD=${ARTIFACTORY_CREDENTIALS_PSW}" \
          --env-file .env1 \
          "${ARTIFACTDATA_IMAGE_NAME}" \
          cat /app/.env \
        > $@

(It is usually better to avoid docker cp, docker exec, and other imperative-type commands; it is fairly inexpensive and better practice to run a new container when you need to.)

If you can't do this, you can docker run --name your choice of names, and then use that container name in the docker cp option.

.PHONY: getmetadata
getmetadata: .env2
.env2: .env1
        docker run --name getmetadata ...
        docker cp getmetadata:/app/.env $@
        docker stop getmetadata
        docker rm getmetadata

If you really can't avoid this at all, each line of the Makefile runs in a separate shell. On the one hand this means you need to join together lines if you want variables from one line to be visible in a later line; on the other, it means you have normal shell functionality available and don't need to use the GNU Make $(shell ...) extension (which evaluates when the Makefile is loaded and not when you're running the command).

.PHONY: getmetadata
getmetadata: .env2
.env2: .env1
        # Note here:
        # $$ escapes $ for the shell
        # Multiple shell commands joined together with && \
        # Beyond that, pure Bourne shell syntax
        ID=$$(docker run -d ...) && \
        echo "$$ID" && \
        docker cp "$$ID:/app/.env" "$@"

Upvotes: 1

Related Questions