Book Image

The DevOps 2.1 Toolkit: Docker Swarm

By : Viktor Farcic
Book Image

The DevOps 2.1 Toolkit: Docker Swarm

By: Viktor Farcic

Overview of this book

Viktor Farcic's latest book, The DevOps 2.1 Toolkit: Docker Swarm, takes you deeper into one of the major subjects of his international best seller, The DevOps 2.0 Toolkit, and shows you how to successfully integrate Docker Swarm into your DevOps toolset. Viktor shares with you his expert knowledge in all aspects of building, testing, deploying, and monitoring services inside Docker Swarm clusters. You'll go through all the tools required for running a cluster. You'll travel through the whole process with clusters running locally on a laptop. Once you're confident with that outcome, Viktor shows you how to translate your experience to different hosting providers like AWS, Azure, and DigitalOcean. Viktor has updated his DevOps 2.0 framework in this book to use the latest and greatest features and techniques introduced in Docker. We'll go through many practices and even more tools. While there will be a lot of theory, this is a hands-on book. You won't be able to complete it by reading it on the metro on your way to work. You'll have to read this book while in front of the computer and get your hands dirty.
Table of Contents (22 chapters)
Title Page
Credits
About the Author
www.PacktPub.com
Customer Feedback
Preface
11
Embracing Destruction: Pets versus Cattle

Running staging tests


Please note that the real purpose of this step in the CI flow is to run the tests that require the service and its dependencies to be running. Those are still not integration tests that require production or production-like environment. The idea behind those tests is to run the service together with its direct dependencies, run the tests, and, once they're finished, remove everything and free the resources for some other task. Since these are still not integration tests, some, if not all, dependencies can be mocks.

Due to the nature of these tests, we need to split the task into three actions:

  1. Run the service and all the dependencies.
  2. Run the tests.
  3. Destroy the service and all the dependencies.

 

The dependencies are defined as the staging-dep service inside the docker-compose-test-local.yml (https://github.com/vfarcic/go-demo/blob/master/docker-compose-test-local.yml) file. The definition is as follows:

  staging-dep:
    image: go-demo
    ports:
      -8080:8080
    depends_on:
      - db

  db:
    image: mongo:3.2.10

The image is go-demo, and it exposes the port 8080 (both on the host and inside the container). It depends on the service db which is a mongo image. Services defined as depends_on will be run before the service that defines the dependency. In other words, if we run the staging-dep target, Compose will run the db first.

Let's run the dependencies as shown in the following code:

docker-compose \ 
    -f docker-compose-test-local.yml \
    up -d staging-dep

Once the command is finished, we will have two containers running (go-demo and db). We can confirm that by listing all the processes:

docker-compose \ 
    -f docker-compose-test-local.yml \
    ps

The output is as follows:

Name                 Command               State Ports
---------------------------------------------------------------------
godemo_db_1          /entrypoint.sh mongod Up    27017/tcp
godemo_staging-dep_1 go-demo               Up    0.0.0.0:8080->8080/tcp

Now that the service and the database it depends on are running, we can execute the tests. They are defined as the service staging. The definition is as follows:

  staging:
    extends:
      service: unit
    environment:
      - HOST_IP=localhost:8080
    network_mode: host
command: bash -c"go get -d -v -t && go test --tags integration -v"

Since the definition of the staging tests is very similar to those we run as unit tests, the staging service extends unit. By extending a service, we inherit its full definition. Further on, we defined an environment variable HOST_IP. The tests code uses that variable to determine the location of the service under test. In this case, since the go-demo service is running on the same server as tests, the IP is server's localhost. Since, by default, localhost inside a container is not the same as the one on the host, we had to define network_mode as host. Finally, we defined the command that should be executed. It will download tests dependencies go get -d -v -t and run the tests go test --tags integration -v.

Let's run the following commands:

docker-compose \ 
    -f docker-compose-test-local.yml \ 
    run --rm staging

All the tests passed, and we are one step closer to the goal of having full confidence that the service is indeed safe to be deployed to production.

We don't have any use for keeping the service and the database running so let's remove them and free the resources for some other task:

docker-compose \ 
    -f docker-compose-test-local.yml \ 
    down

The down command stops and removes all services defined in that Compose file. We can verify that by running the following  ps command:

docker-compose \ 
    -f docker-compose-test-local.yml \ 
    ps

The output is as follows:

Name   Command   State   Ports
------------------------------

There is only one thing missing for the CI flow to be complete. At this moment we have the go-demo image that is usable only inside the go-demo server. We should store it in a registry so that it can be accessed from other servers as well.