I like Docker. I use it almost everything. 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 <balazs.nadasdi@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 <balazs.nadasdi@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
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)