Ayush
Ayush

Reputation: 42450

Docker image for built Golang binary

I have a Go application that I build into a binary and distribute as a Docker image.

Currently, I'm using ubuntu as my base image, but this causes an issue where if a user tries to use a Timezone other than UTC or their local timezone, they get an error stating:

pod error: panic: open /usr/local/go/lib/time/zoneinfo.zip: no such file or directory

This error is caused because the LoadLocation package in Go requires that file.

I can think of two ways to fix this issue:

  1. Continue using the ubuntu base image, but in my Dockerfile add the commands: RUN apt-get install -y tzdata

  2. Use one of Golang's base images, eg. golang:1.7.5-alpine.

What would be the recommended way? I'm not sure if I need to or should be using a Golang image since this is the container where the pre-built binary runs. My understanding is that Golang images are good for building the binary in the first place.

Upvotes: 3

Views: 3571

Answers (4)

Taku
Taku

Reputation: 5937

Since not all OS have localized timezone installed, this is what I did to make it work:

ADD https://github.com/golang/go/raw/master/lib/time/zoneinfo.zip /usr/local/go/lib/time/zoneinfo.zip

The full example of multi-step Docker image for adding timezone is here

Upvotes: 2

dustinevan
dustinevan

Reputation: 977

This is more of a vote, but apt-get is what we (my company's tech group) do in situations like this. It gives us complete control over the hierarchy of images, but this is assuming you may have future images based on this one.

Upvotes: 1

Tuo Shan
Tuo Shan

Reputation: 51

You can use the system's tzdata. Or you can copy $GOROOT/lib/time/zoneinfo.zip into your image, which is a trimmed version of the system one.

Upvotes: 1

Eugene Lisitsky
Eugene Lisitsky

Reputation: 12895

I prefer to use multi-stage build. On 1st step you use special golang building container for installing all dependencies and build an application. On 2nd stage I copy binary file to empty alpine container. This allows having all required tooling and minimal docker image simultaneously (in my case 6MB instead of 280MB).

Example of Dockerfile:

# build stage
FROM golang:1.8
ADD . /src
RUN set -x && \
    cd /src && \
    go get -t -v github.com/lisitsky/go-site-search-string && \
    CGO_ENABLED=0 GOOS=linux go build -a -o goapp

# final stage
FROM alpine
WORKDIR /app
COPY --from=0 /src/goapp /app/
ENTRYPOINT /goapp
EXPOSE 8080

Upvotes: 3

Related Questions