Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a binary that contains zoneinfo.zip

I'm using Docker to create a container application and then deploy it to kubernetes engine but when the application is been initialized I get this error:

err: open C:\Go/lib/time/zoneinfo.zip: no such file or directory

enter image description here

enter image description here

like image 714
John Balvin Arias Avatar asked Dec 10 '22 05:12

John Balvin Arias


2 Answers

You might consider building your Go application with Go 1.15 (August 2020, two years later)

New embedded tzdata package

Go 1.15 includes a new package, time/tzdata, that permits embedding the timezone database into a program.

  • Importing this package (as import _ "time/tzdata") permits the program to find timezone information even if the timezone database is not available on the local system.
  • You can also embed the timezone database by building with -tags timetzdata.

Either approach increases the size of the program by about 800 KB.

That way, once deployed to a Kubernetes engine as a Docker image, it won't have to try and load any timezone information, since said information is embedded in its program.

Caveat: as commented by dolmen:

This solution has the drawback that the timezone information version is linked to the version of Go you use for building.

If you keep using a fixed version of Go for your project, you will keep timezones from that version.

Being able to update the timezone information independently from the Go version (update every time you rebuild the Docker image for deploy) might be a better choice.

As an illustration, see dolmen's answer.

like image 129
VonC Avatar answered Dec 31 '22 17:12

VonC


When using Go's time package, specifically the LoadLocation method, it looks for time zone database information in various locations. This is explained in the comments for LoadLocation in the source code at https://golang.org/src/time/zoneinfo.go. Specifically it looks in these places:

  1. A location specified by a ZONEINFO environment variable
  2. Known locations where time zone database files are kept on Unix operating systems
  3. The zoneinfo.zip file in your $GOROOT

When you're programming on a Windows machine, Go is most likely defaulting to the 3rd option. However, there is no $GOROOT when you're working with a binary, so that won't work in your container. On most versions of Linux the 2nd option would work fine as they would have the necessary time zone database files. However, I have a strong suspicion that the optimized container you reference does not. This leaves you with option 1, which essentially consists of putting your own time zone database files on the container and then referencing their location with the ZONEINFO environment variable. This is both kind of a pain in the ass and I've also found that it fails silently when you request a time zone file that doesn't exist.

In my own addressing of this problem I ended up creating a package that utilizes the LoadLocationFromTZData method and tries to simplify the process of providing and working with your own copy of the time zone database. You can see my own stack overflow question here: Detect if ZONEINFO fails in Go. And you can see the repository for my time zone package here: https://github.com/slotheroo/knozone

like image 45
Slotheroo Avatar answered Dec 31 '22 19:12

Slotheroo