
Automating the workflow
At this point, you have managed to successfully configure Docker Compose to build, test, and create a working local environment for the sample application, complete with MySQL database integration and acceptance tests. You can now stand up this environment with a handful of commands, but even though using Docker Compose has significantly simplified the commands you need to run, it is still difficult to remember which commands to use and in which order. Ideally we want a single command to run the complete workflow, and this is where a tool such as GNU Make is very useful.
Make has been around a long time, and is still considered the build tool of choice for many C and C++ applications. Task automation is a key feature of Make, and the ability to define tasks or targets in a simple format that can be invoked with a single command has made Make a popular automation tool, particularly when dealing with Docker containers.
By convention make looks for a file, called Makefile, in the current working directory, and you can create a very simple Makefile, as demonstrated here:
hello:
@ echo "Hello World"
echo "How are you?"
In the preceding example, you create a target called hello with two shell commands, which you can execute by running make <target>, or make hello in this example. Each target can include one or more commands, which are executed in the sequence provided.
One important point to note is that make expects tabs (not spaces) to be used when you define the various commands for a given target, so if you receive a missing separator error, such as Makefile:2: *** missing separator. Stop., check that you have used tabs to indent each command.
> make hello
Hello World
echo "How are you?"
How are you?
In the preceding example, you can see that the output of the each command is displayed on screen. Note that the special @ character on the first command suppresses echoing each command as it is run.
One important piece of housekeeping you should perform in your Makefiles when using them for task automation is to configure the somewhat amusingly-named special target called .PHONY, with the names of each target that you will be executing:
.PHONY: hello
hello:
@ echo "Hello World"
echo "How are you?"
Because make is really a build tool for compiling source code files, the .PHONY target tells make that if it sees a file named hello, it should still run the target. If you didn't specify .PHONY and there was a file called hello in the local directory, make would exit stating that the hello file has already been built. This clearly doesn't make much sense when you are using make to automate tasks, so you should always use the .PHONY target to avoid any strange surprises.