Over a million developers have joined DZone.

Making a Minimal Docker Container

Default Docker containers contain base OS images with utilities and libraries. Here's how you can start from scratch and get a tiny image.

· Cloud Zone

Download the Essential Cloud Buyer’s Guide to learn important factors to consider before selecting a provider as well as buying criteria to help you make the best decision for your infrastructure needs, brought to you in partnership with Internap.

Most Docker images start from the Docker Hub, with its set of base OS images and application images built from them. With Docker’s layered architecture for images, the fact that typical images are 50MB to 100MB is not a major issue.

At the same time, there are uses for Docker where building from scratch is desirable, and when building from scratch, the image might as well be as small as possible.

Of course, the reason the base OS images are the size they are is because they include base utilities and dynamically linked libraries. If our purpose is just to run a statically linked application, only the application file needs to be included in the Docker image.

The Go programming language provides statically linked executables (with the right compiler flags). I’ve been working with Go and figured it would be interesting to try out packing a small sample application into a Docker container.

The Go application is basic:

package main

import (
        "fmt"
        "log"
        "net/http"
        "os"
)

func ArgServer(w http.ResponseWriter, req *http.Request) {
        fmt.Fprintln(w, os.Args)
}

func main() {
        http.Handle("/args", http.HandlerFunc(ArgServer))
        log.Fatal(http.ListenAndServe(":8080", nil))
}

This application uses the net/http library, which is one library that Go potentially links dynamically, so it makes a good example for creating a statically linked Go executable. It also uses command-line arguments, allowing those to be demonstrated as well.

To create a fully statically linked version of this application, I used the following compile command:

CGO_ENABLED=0 GOOS=linux go build -a -tags netgo -ldflags '-w' ...argserver

According to this article this form only works with Go 1.3 or older, but for me this command worked fine while running Go 1.5.1. If you do have trouble, the linked article suggests using installsuffix to keep static versions of components separate in newer versions of Go.

With the argserver executable and a Dockerfile in the current directory, this command will create and tag our minimal Docker image:

docker build -t argserver .

Here is the Dockerfile:

FROM scratch

ADD argserver /argserver

ENTRYPOINT ["/argserver"]

CMD ["a", "b", "c", "d"]

Note that we start from “scratch”, we add only the single executable, and we set it as the entry point. The CMD line provides default arguments which we can override.

When running this image, it is necessary to expose port 8080 outside the container so we can access the HTTP server:

docker run -d -p 8081:8080 argserver

This command will run the container in the background and map port 8081 on the host to port 8080 in the container. We can then access the HTTP server:

> curl http://localhost:8081/args
[/argserver a b c d]

Or, we could override the command line args:

> docker run -d -p 8081:8080 argserver g h i j
> curl http://localhost:8081/args
[/argserver g h i j]

When testing this with Ubuntu Wily running Go 1.5.1, the resulting Docker image was 4.9MB. Most of this is static libraries. We could add quite a bit more HTTP server functionality without the image getting much larger.

The Cloud Zone is brought to you in partnership with Internap. Read Bare-Metal Cloud 101 to learn about bare-metal cloud and how it has emerged as a way to complement virtualized services.

Topics:
docker ,go language ,go ,golang

Published at DZone with permission of Alan Hohn, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}