How I Fixed: docker: invalid reference format With Makefile

I’m a big fan of makeshift Makefiles. Largely because I don’t seem to have the brain capacity to remember long winded commands. Or maybe, I just don’t like typing out long winded commands. One of the two reasons, for sure.

In using a Makefile to set up a local DNS server to help resolve an issue with multiple different related, but separated Docker projects being able to talk to one another, I ended up coming across this Stack Overflow post which was very helpful.

The solution from the post calls for running a Docker command to spin up a local DNS server, which then allows all the disparate services to talk to one another via hostname, rather than IP address.

I dutifully created a new Makefile entry:

start_dev_dns:
	@docker run \
		--rm \ 
		--hostname=dns.mageddo \
		-p 5380:5380 \
		-v /var/run/docker.sock:/var/run/docker.sock \
		-v /etc/resolv.conf:/etc/resolv.conf \
		defreitas/dns-proxy-server

It’s hard to spot the fault here. That command looks right to me.

I copy / pasted the command direct from the Stack Overflow post, added in the --rm flag to ensure the resulting container gets removed when I kill it, and then tried to run the command:

 ➜ myproject.whatever make start_dev_dns
docker: invalid reference format.
See 'docker run --help'.
make: *** [Makefile:8: start_dev_dns] Error 125

Boo.

Anyway, after a bit of head scratching, it turns out the issue was an extra space after the line continuation slash.

Really hard to display this one on a blog post. But essentially if you see this and you’re in a similar situation, check you don’t have any rogue spaces after the \‘s at the end of each line.

A Makefile To Run Makefiles

Here’s a small helper thingy that I use to help manage multiple docker-compose setups in production. But this will work with anything that uses Makefiles.

The idea is that I have a helpful Makefile per docker-compose project, as kinda mentioned in this post.

In short, using a Makefile per project allows me to mask away some long winded commands that make kick starting each environment much easier than it may otherwise have been.

The problem is that I have one Makefile per project directory, and some projects have several services. An example might be a project with:

  • www
  • api
  • management console
  • demo site

And so on.

Whilst it’s nice to have one command per service, it does still mean I have to log on to the server, cd to each dir, then run the make start command. And in some cases this needs to be done in a particular order, so that dependant services are up before workers try to connect, and so on.

A better way is to have one Makefile in the project root dir, which then calls the make start command in each sub dir. Something like this:

touch /docker/myproject.com/Makefile
vim /docker/myproject.com/Makefile

start:
    make start --directory /docker/myproject.com/api && \
        make start --directory /docker/myproject.com/admin && \
        make start --directory /docker/myproject.com/www

This way I can now just run one command on the project root dir, and it will take care of calling all the sub tasks that kick start the project.