Every Continuous Integration process starts with a code that is checked out from a repository. We'll use the GitHub repository vfarcic/go-demo (https://github.com/vfarcic/go-demo) throughout the book. It contains the code of the service we'll use throughout the book. The service is written in Go (https://golang.org/). Fear not! Even though I consider it one of the best currently available languages, you will not be required to learn Go. We'll use the go-demo service only as a demonstration of the processes explained throughout the book. Even though I strongly recommend learning Go, the book does not assume any knowledge of the language. All the examples will be programming language agnostic.
Please make sure that your Git client is configured to check out the code AS-IS. Otherwise, Windows might change carriage returns to the Windows format.
Let's get going and check out the go-demo code:
git clone https://github.com/vfarcic/go-demo.git
cd go-demo
Some of the files will be shared between the host file system and Docker Machines we'll start creating soon. Docker Machine makes the whole directory that belongs to the current user available inside the VM. Therefore, please make sure that the code is checked out inside one of the user's sub-folders.
Now that we have the code checked out from the repository, we need a server that we'll use to build and run tests. For now, we'll use Docker Machine, since it provides an easy way to create a "Docker ready" VMs on our laptops.
The Docker Machine (https://docs.docker.com/machine/overview/) is a tool that lets you install Docker Engine on virtual hosts, and manage the hosts with the docker-machine commands. You can use Machine to create Docker hosts on your local Mac or Windows box, on your company network, in your data center, or on cloud providers like AWS or DigitalOcean.
Using docker-machine commands, you can start, inspect, stop, and restart a managed host, upgrade the Docker client and daemon, and configure a Docker client to talk to your host.
Machine was the only way to run Docker on Mac or Windows previous to Docker v1.12. Starting with the beta program and Docker v1.12, Docker for Mac and Docker for Windows are available as native apps and the better choice for this use case on newer desktops and laptops. I encourage you to try out these new apps. The installers for Docker for Mac and Docker for Windows include Docker Machine, along with Docker Compose.
The recommendation is to run all the examples from Git Bash (installed through Docker Toolbox as well as Git). That way the commands you'll see throughout the book will be same as those that should be executed on OS X or any Linux distribution.
Docker Machine on Linux might not be able to mount a host volume inside VMs. The problem is related to the fact that both host and Docker Machine OSes use /home directory. Mounting /home from the host would overwrite some of the required files. If you experience problems with mounting of the host volume, please export the VIRTUALBOX_SHARE_FOLDER variable:
export VIRTUALBOX_SHARE_FOLDER="$PWD:$PWD"
If machines are already created, you'll have to destroy them and create them again.
Please note that this problem should be fixed in newer Docker Machine versions so use this workaround only if you notice that the volume is not mounted (files from the host are not available inside VMs).
Let's create our first server called go-demo use the following command:
docker-machine create -d virtualbox go-demo
If you're using Docker for Windows instead of Docker Toolbox, you will need to change the driver from virtualbox to Hyper-V. The problem is that Hyper-V does not allow mounting host volumes, so it is still highly recommended to use Docker Toolbox when working with Docker Machine. The reason behind the choice of running Docker inside Docker Machines instead natively on the host lies in the need to run a cluster (coming in the next chapter). Docker Machine is the easiest way to simulate a multi-node cluster.
The command should be self-explanatory. We specified virtualbox as the driver (or Hyper-V if you're running Docker for Windows) and named the machine go-demo:
In some cases, Git Bash might think that it is still running as BAT. If you experience a problem with the docker-machine env commands, please export the SHELL variable:
export SHELL=bash
Now that the machine is running, we should instruct our local Docker Engine to use it, use the following command:
docker-machine env go-demo
The docker-machine env go-demo command outputs environment variables required for the local engine to find the server we'd like to use. In this case, the remote engine is inside the VM we created with the docker-machine create command.
The output is as follows:
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/vfarcic/.docker/machine/machines/go-demo"
export DOCKER_MACHINE_NAME="go-demo"
We can envelop the env command into an eval that will evaluate the output and, in this case, create the environment variables using the following command:
eval $(docker-machine env go-demo)
From now on, all the Docker commands we execute locally will be channeled to the engine running inside the go-demo machine.
Now we are ready to run the first two steps in the CI flow. We'll execute unit tests and build the service binary.