Multi-stage Builds, Docker Image Size Reduction

Eren Akbulut
Jan 11 · 4 min read

Hello everyone, today I’ll try to explain how to create multi-stage Docker builds in order to decrease build size with Dockerfile on a small Go application and the latest GoLang image from DockerHub.

Through this tutorial I won’t publish any code snippets directly, I’ll instead give you a repo to copy and paste.

First, we’ll create a really basic Go webserver using the Mux package. “Package gorilla/mux implements a request router and dispatcher for matching incoming requests to their respective handler." from their GitHub page. You can also learn how to install that package on your local from the link.

After that, we need to create a main.go file with the following content.

Image for post
Image for post

After we create our main.go we can go ahead and initialize a go module with the command:

go mod init (nameselectionforappofyourchoice)

Then we can check if the server is up by running our application with the command:

go run .

Then we should quickly create a Dockerfile in same directory and the final look of our project should be like this one now.

Image for post
Image for post

Writing our Dockerfile is a little bit more tricky but I’ll try to explain each step.

Image for post
Image for post
  1. We pull golang image with a specific version from DockerHub.
  2. We create a directory for ourselves in our container.
  3. We copy go.sum and go.mod files to our directory from the line above.
  4. We download our dependencies.
  5. We copy everything from our current directory to our directory in the container.
  6. We should run go build in order to get a statically compiled go binary. (Actually, all we want to do in this tutorial is to use a statically compiled Go application and with that binary in our hands, we can run it even in a smaller Docker image like Alpine with no real ability to compile a Go application.) CGO_ENABLED=0 for static compile and -o flag indicates the output folder.
  7. We pull another image called Alpine from DockerHub with a smaller build size.
  8. We copy /bin/app folder from our older stage to /bin/app folder in new image.
  9. We define /bin/app as our entrypoint

We are good to go now. We can build and run our container with the following commands:

docker build -t <tagselectionofyourchoice> docker run -p 5000:8080 <tagselectionofyourchoice> ## Opening a port from our Go app 8080 to our local port 5000.

Image for post
Image for post

Now our Dockerized app is up at port 5000.

Image for post
Image for post

Now we as we can see our container is fully functional yet the image size is significantly smaller. I will not share another picture for it but the original Golang image usually takes around 900MB of space alone. This is thanks to the static compiling abilities of Golang.

I hope that tutorial can help you. I’ll see you in the next blog posts :).

Originally published at https://blog.akbuluteren.com.

Image for post
Image for post

👋 Join FAUN today and receive similar stories each week in your inbox! Get your weekly dose of the must-read tech stories, news, and tutorials.

Follow us on Twitter 🐦 and Facebook 👥 and Instagram 📷 and join our Facebook and Linkedin Groups 💬

Image for post
Image for post

FAUN

The Must-Read Publication for Creative Developers & DevOps Enthusiasts

Sign up for FAUN

By FAUN

Medium’s largest and most followed independent DevOps publication. Join thousands of aspiring developers and DevOps enthusiasts Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Eren Akbulut

Written by

Developer, M.Sc. Student, github.com/eren23, akbuluteren.com

FAUN

FAUN

The Must-Read Publication for Creative Developers & DevOps Enthusiasts. Medium’s largest DevOps publication.

Eren Akbulut

Written by

Developer, M.Sc. Student, github.com/eren23, akbuluteren.com

FAUN

FAUN

The Must-Read Publication for Creative Developers & DevOps Enthusiasts. Medium’s largest DevOps publication.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store