Practical Skills to Simplify Your Builds Using Docker

November 14, 2021

If you’ve worked with Docker before, you know how convenient it is to use to run your apps in containers. (For a primer on Docker, check out this course on building and running your first Docker app from Dan Whalin.)

Docker containers give you a consistent way to package and run your applications, but they can also power up your software builds. Essentially, you can use Docker to compile apps inside containers—making Docker your build server and ditching the need to install any SDKs or runtimes to build and run your app from source.

The beauty of building inside containers

Building inside containers means that everything becomes super portable, freeing you from having to consider what’s happening at the technology level.

You could have an application running in Windows containers with an extension of what I’ve shown you today, with a proxy and a web app, on a database, for example.

Or you could have a micro-service-base app that’s running in Linux containers with a web component and several services sitting behind the scenes. With Docker, you have the same set of tools to build them with.

In the past, developers had a massive separation between their work when they run, which was completed using Visual Studio and the F5 function, and when they complete the build process, which was completed using scripts.

Today, with Docker, those gaps are removed, and issues occur within the dependency, whether you’re using Linux or Windows or a combination of the two. You can use the same pipelines and technologies.

And if you’re moving toward DevOps, it helps alleviate the need for separate dev and ops teams. With Docker, the teams use the same technologies and languages (Dockerfiles and Compose files). Suddenly, they’re all speaking the same language, making it simpler to work together and own projects jointly.


Containers 101

As a quick review, you install Docker on your server or set of servers and send the instructions to the Docker API running on the server. Docker runs those processes for you inside these lightweight virtualized environments called containers.

For example, three containers are running in this example, and the app components inside each of those containers can see a different compute environment. While each container has its own IP address and access to RAM, they’re all running the processes natively on the server; this gives you isolation between the containers, but they’re super lightweight because they all use the same operating system running on the surface.


Practical skills to simplify your project builds

This article walks you through a series of demonstrations to help you understand how to achieve this type of next-level portability. The first demo provides a refresher on Docker and Compose and will help set the stage for the demos that follow, where we’ll also cover how to:

· Leverage multi-stage Dockerfiles

· Build distributed apps using Docker Compose and plug your software builds into a managed CI service with GitHub Actions

Demo 1: Refresher on Docker and Docker Compose

The first demo provides a refresher on Docker and Docker compose. It shows how all the pieces fit together and lays the groundwork for the later demos. This demo uses the sixeyed/pi repo.


Three steps to take that will let you use Docker as your build environment

1. The first step is to run two containers which are components of the same app, as follows:

docker network create pi

docker run -d --network pi --name pi-web -e Computation:Metrics:Enabled=false sixeyed/pi:20.05 -m web

docker run -d --network pi -p 8314:80 sixeyed/pi:proxy-20.05

Use the app at http://localhost:8314/pi?dp=5000


2. Next, use Compose to define the desired state of your app.  This docker-compose.yml file describes the same app in a declarative way.

Remove the existing containers:

docker rm -f $(docker ps -aq)

Deploy again with Compose:

docker-compose -f ./demo1/docker-compose.yml up -d

docker ps

Once this step is completed, test it at http://localhost:8314/pi?dp=10000


3. The next step is to package Containers on top of a base image with the app runtime. This should be as small as possible with no unnecessary tools; for Java:

docker container run -it --entrypoint sh openjdk:11-jre-slim

java --version

javac --version


You can also run a container with a full development environment, like Maven:

docker container run -it --entrypoint sh maven:3.6.3-jdk-11

java --version

javac --version

mvn --version



And that lets you use Docker as your build environment.


Demo 2: Use different base images for different tasks with multi-stage Dockerfiles

In the first part of this demo,we’ll use an SDK image to compile the app.  In the second part, we’ll use the runtime image and copy in the compiled app. This demo uses the sixeyed/ repo.

1. Use an SDK image to compile the app. This Dockerfile for a .NET Core app shows how it works.

cd D:/scm/github/sixeyed/


docker build -t signup-web-core -f ./docker/frontend-web/signup-web-core/Dockerfile .

Next, edit the CS and rebuild, which is done mostly from cache.

Add-Content -Value '//' -Path D:\scm\github\sixeyed\\src\SignUp.Web.Core\Program.cs


docker build -t signup-web-core -f ./docker/frontend-web/signup-web-core/Dockerfile .

2. You can use the same concept to compile for other languages. For example, see this Dockerfile for a .NET Fx app.

Switch to Windows containers

docker version


docker build -t signup-web -f ./docker/frontend-web/v2/Dockerfile .


Demo 3: Add build details to Docker Compose files and build all your images with a single command.

In this last demo we’ll walk through how to add build details to Docker Compose files so you can build all your images with a single command and check the GitHub Actions workflows so you see how to plug your software builds into a managed CI service with GitHub Actions. This demo uses the sixeyed/diamol repo.

1. To add build details to Docker Compose files, begin by accessing the docker-compose.yml file, which is for a multi-container app with different tech steps. This step works with Linux or Windows containers.

cd D:/scm/github/sixeyed/diamol

docker-compose build

docker-compose build --pull --no-cache

Next, check out the Dockerfiles:

·   Node.js access-log API

·   Java REST API

·   Go web app

Then, run the app:

docker-compose up -d

Once you’ve completed these steps, check the app at http://localhost:8010

2. Next, check the GitHub Actions workflows in the sixeyed/kiamol repository:

·   ch03 build

·   ch03 compose file

·   ch03 API Dockerfile

·   ch03 sleep Dockerfile

Finally, check out the live builds at


Learn more with Pluralsight

If you’d like to walk through these Docker demonstrations step by step, refer to my webinar, Simplify Your Project Builds with Docker

Plus, Pluralsight publishes a number of resources to help you get up to speed on Docker, DevOps, and so much more. You can find my courses, webinars, and articles on Pluralsight here.

You can also get tips and insights on how to learn Docker in a month of lunches here and learn Kubernetes in a month of lunches here.