3

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.

5
  • If you need the tzdata package, then you need to install that. What image are you building your binary with? Commented Oct 2, 2017 at 18:56
  • I currently do not build within a container. I do intend to fix that by building using the golang:1.7.5-alpine container Commented Oct 2, 2017 at 19:53
  • 1
    If you not building with alpine, you need to be sure you're building a static binary if you intend to release with alpine. Either way you need the zoneinfo in your final container if you're using it in your program. Commented Oct 2, 2017 at 19:56
  • @JimB I am currently building a static binary targeted for my current runtime container. Regarding zoneinfo, I'm trying to figure out the best way to have that in my final container - should I install the tzdata package in my ubuntu container, or use one of golang containers. Commented Oct 2, 2017 at 20:05
  • That's entirely up to you. You can view the associated Dockerfiles, and see if one suits your needs more than the other. There is no "right" answer here Commented Oct 2, 2017 at 23:23

4 Answers 4

3

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
Sign up to request clarification or add additional context in comments.

2 Comments

With this approach, your final runtime container won't have the time data at /usr/local/go/lib/time/ though
@xbonez of couse, if you need some data files what aren't get compiled into binary you can ADD them. This way you get minimal image - only things you need.
2

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

Comments

1

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.

1 Comment

Thanks. Marking this as accepted since this is the approach I ended up going with.
1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.