1

I'm new to Makefiles, I'm trying to use one to help me automate the build of my docker images.

I'm struggling to write, what feels like, a simple recipe that does the following:

  • Check to see if there are running containers (docker ps -a -q)
  • If running containers exist remove them (docker rm $(docker ps -a -q))

This is what I've manage to cobble together so far through various Google searches:

DOCKER_CONTAINER_LIST := $(shell docker ps -a -q)

clean-docker:
    if [[ ! $(DOCKER_CONTAINER_LIST) == "" ]];then \ 
        docker rm $$(docker ps -a -q) \ 
    fi

Which yields the following output:

if [[ de6e694da4f9 == "" ]];then \
/bin/sh: -c: line 0: conditional binary operator expected
/bin/sh: -c: line 0: syntax error near 'de6e694da4f9'
/bin/sh: -c: line 0: 'if [[ de6e694da4f9 == "" ]];then \ '
make: *** [clean-docker] Error 2

Would be great if someone could show me how to achieve this please

UPDATE

Thank @I0b0 for your answer, I think I'm almost there now. The Makefile now looks like this:

DOCKER_CONTAINER_LIST := $(shell docker ps -a -q)

clean-docker:
    if [ -n "$(DOCKER_CONTAINER_LIST)" ] \
    then \
        docker rm "$(DOCKER_CONTAINER_LIST)" \
    fi

But I get the following error when running it:

if [ -n "6778d35e5c95" ] \
then \
docker rm "6778d35e5c95" \
fi
/usr/bin/sh: -c: line 4: syntax error: unexpected end of file
make: *** [clean-docker] Error 1

I had a look at this answer regarding line endings, but that made no difference. I am using Makefile on both Mac and Windows.

GreenyMcDuff
  • 3,292
  • 7
  • 34
  • 66

3 Answers3

1

It can be done with:

# for images
docker rmi $(shell docker images -a -q)

# for containers
docker rm $(shell docker ps -a -q)

# for volumes
docker volume rm $(shell docker volume ls -q)

PS. macOS

Dos
  • 841
  • 10
  • 23
0

if [ -n "$(DOCKER_CONTAINER_LIST)" ] should do it:

Bonus points for reusing the variable with docker rm "$(DOCKER_CONTAINER_LIST)".


After the update the problem is related to a fundamental difference between scripts and makefiles: the latter cannot be broken into lines in the exact same way as scripts by just adding backslashes before the end of line. What you've ended up with is a single line if [ -n "$(DOCKER_CONTAINER_LIST)" ] then docker rm "$(DOCKER_CONTAINER_LIST)" fi. Because newlines in a makefile don't work like ; in a shell script you have to add two:

if [ -n "$(DOCKER_CONTAINER_LIST)" ]; \
then \
    docker rm "$(DOCKER_CONTAINER_LIST)"; \
fi
l0b0
  • 55,365
  • 30
  • 138
  • 223
  • 1
    Thanks @I0b0, that's almost done it, but I'm now struggling with an `unexpected end of file` error. I've added some more info to the question, don't suppose you know why that might be happening? – GreenyMcDuff Jun 09 '19 at 20:14
0

I couldn't figure out how to divide those commands into multiple lines either, but ugly oneliners work for me.

So what you were asking about would be something like this

DOCKER_CONTAINER_LIST := $(shell docker ps -a -q)

clean_docker:
    @if [ -n "$(DOCKER_CONTAINER_LIST)" ]; then echo "Removing docker containers" && docker rm "$(DOCKER_CONTAINER_LIST)"; else echo "No containers found"; fi;
Tom Wojcik
  • 5,471
  • 4
  • 32
  • 44