Docker multi-stage build


dark-flight-launch-73872I recently came across a really nice feature of Docker Build and wanted to share it.

Building a Docker Image often requires to build binaries.  In my case I needed to build a .NET core application.  You might need to build a Java App or any other types of apps.

I was using my Docker sandbox VM to perform Docker builds.  I really like that VM image since each time I create a new one I get a fresh image.  It doesn’t have .NET core SDK on it though.  I could install it but it broke the experience a little.

I thought about setting up my Continuous Integration service.  I was wondering…  what is better to setup an isolated environment than a container?  Then discovered multi-stage build.  Special thanks to my colleague Maxime Rouiller for that discovery!

Multi-stage allows us to build many images and exchange files between them.  We can perform compilation in an image and use the output in another.  We can do that multiple times, in multiple stages.

Let me share the details with you!

Background

First for a little background, see our article on Overview of Containers in Azure.

We also have a Getting started with Containers in Azure.

We wrote many more articles on containers.

Multi-Stage builds

Docker has a nice article around multi-stage builds.  We won’t repeat the content here.  Instead, we’ll give an example with our recent Cosmos DB Configuration Management tool.  The tool is deployed as a Docker Image available on Docker Hub.

The Docker file, available on GitHub is reproduced here:


#    Multi-stage docker build file (see <a href="https://docs.docker.com/develop/develop-images/multistage-build/)">https://docs.docker.com/develop/develop-images/multistage-build/)</a>
#    Use a Microsoft image with .NET core runtime (<a href="https://hub.docker.com/r/microsoft/dotnet/tags/)">https://hub.docker.com/r/microsoft/dotnet/tags/)</a>
FROM microsoft/dotnet:2.1-sdk AS build

WORKDIR /src

#    Copy source code into the source folder
COPY . .

#    Publish the app into the app folder
RUN dotnet publish . -c release -o app

###########################################################
#    Final container image
#    Use a Microsoft image with .NET core runtime (<a href="https://hub.docker.com/r/microsoft/dotnet/tags/)">https://hub.docker.com/r/microsoft/dotnet/tags/)</a>
FROM microsoft/dotnet:2.1-runtime AS final

#    Set the working directory to /work
WORKDIR /work

#    Copy package
COPY --from=build /src/app .

#    Define environment variables
ENV ACCOUNT_ENDPOINT ""
ENV ACCOUNT_KEY ""
ENV TARGET_URL ""

#    Run console app
CMD ["dotnet", "CosmosTargetConsole.dll"]

Let’s review that Docker File.

At line 3, we declare an image build from microsoft/dotnet:2.1-sdk.  That Docker image contains .NET core SDK.  It isn’t optimal for a runtime image which is what we need in the end.  It is required to build .NET core applications though.

We give the image a name by using AS build.  We will refer to that image in the next stage.

We then copy files from the host environment (the VM).  Those files are the GitHub source files.

In line 11, we build (with the publish command) our application.

In line 16, we declare another image.  That image is based on the leaner microsoft/dotnet:2.1-runtime image.  That image doesn’t contain the SDK.

In line 22, we copy the build output from the build image.

After that we simply declare environment variables and define the entry point command.

Advantages of multi-stage builds

The advantages of multi-stage builds are:

  • Have a consistent build environment to build an application
  • No compromise on the Docker Image we are building.  Do not include SDKs and other build-artefacts.

Summary

I hope this feature will prove as useful as it did for us.

It is quite easy to use and streamlined a lot of operations for us.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s