Last Updated: September 23, 2016
·
32.71K
· yitsushi

Docker, why I prefer Alpine as base instead of Ubuntu

A few months ago, I started every Dockerfile with this line:

FROM ubuntu:xx.xx

where xx.xx is the latest LTS version. Ok nice. After I used Docker I realised, the size and time matter. I started to seek a new base image that fits my needs and smaller (quicker build). I found Alpine. It's awesome.

Here is an ubuntu based Dockerfile to run my sample Go project:

FROM ubuntu

MAINTAINER Balazs Nadasdi <yitsushi@cheppers.com>

# Update package index and install go + git
RUN apt-get update -q \
    && apt-get install -yq golang git-core

# Set up GOPATH
RUN mkdir /go
ENV GOPATH /go

# Get dependencies
RUN go get gopkg.in/mgo.v2 && \
    go get github.com/go-martini/martini && \
    go get gopkg.in/redis.v3

# Add current working directory
ADD . /go/src/github.com/Yitsushi/livetogether

# Build it :)
RUN go install github.com/Yitsushi/livetogether

# Every time I start the container I want to rebuild
# because I mount it when I use it for development
ENTRYPOINT go install github.com/Yitsushi/livetogether && \
           /go/bin/livetogether --config=/go/src/github.com/Yitsushi/livetogether/config.json

# Expose where the application wants to listen
EXPOSE 8080

And now see with Alpine:

FROM alpine

MAINTAINER Balazs Nadasdi <yitsushi@cheppers.com>

# Update package index and install go + git
RUN apk add --update go git

# Set up GOPATH
RUN mkdir /go
ENV GOPATH /go

# Get dependencies
RUN go get gopkg.in/mgo.v2 && \
    go get github.com/go-martini/martini && \
    go get gopkg.in/redis.v3

# Add current working directory
ADD . /go/src/github.com/Yitsushi/livetogether

# Build it :)
RUN go install github.com/Yitsushi/livetogether

# Every time I start the container I want to rebuild
# because I mount it when I use it for development
ENTRYPOINT go install github.com/Yitsushi/livetogether && \
           /go/bin/livetogether --config=/go/src/github.com/Yitsushi/livetogether/config.json

# Expose where the application wants to listen
EXPOSE 8080

And now see our base images:

❯ docker images | awk '{print $1"\t"$2"\t"$7" "$8}'
REPOSITORY  TAG SIZE
ubuntu  latest  187.9 MB
redis   latest  109.3 MB
mongo   latest  261.6 MB
golang  latest  709.5 MB
alpine  latest  5.249 MB

Build time?

❯ time docker build -t sample_ubuntu livetogetheru/
...
docker build -t sample_ubuntu livetogetheru  0.17s user 0.03s system 0% cpu 6:22.66 total
❯ time docker build -t sample_alpine livetogether/
...
docker build -t sample_alpine livetogether  0.15s user 0.01s system 0% cpu 2:09.89 total

the point:

ubuntu: 6:22.66 total
alpine: 2:09.89 total

Wow... and after the build?

❯ docker images | awk '{print $1"\t"$2"\t"$7" "$8}'
REPOSITORY  TAG SIZE
sample_alpine   latest  167.6 MB
sample_ubuntu   latest  447.8 MB
<none>  <none>  187.9 MB
ubuntu  latest  187.9 MB
redis   latest  109.3 MB
mongo   latest  261.6 MB
golang  latest  709.5 MB
alpine  latest  5.249 MB

What? 3 times more time to build and 4 times bigger the app image size and more than 30 times bigger the base image? omg!

as you see, don't use the base golang image because it's much more bigger and you don't need it

2 Responses
Add your response

Seriously, what data is in that 5MB? It's too small!

over 1 year ago ·

I said the same at the first time, but it works. As their Wiki shows me, it can be useable as desktop (you can install Gnome, Xfce etc).

http://wiki.alpinelinux.org/wiki/Tutorials_and_Howtos

I could install Go, Ruby (RoR) [Redmine howto: http://wiki.alpinelinux.org/wiki/Redmine]

So it is just awesome. I loved Gentoo as server but not as container base (lol, emerge everything :D that would be waste of time). Now I use Alpine as base. If I meet a problem where I can't use it I will publish it and then I use another distro as base image only for that specific case.

over 1 year ago ·