Timezone setting in Alpine images

Hi,

what would be the setup when your base image is resin-alpine-based ?

Here an extract of my Dockerfile which follows the alpine doc and which doesn’t work with

FROM "resin/%%RESIN_MACHINE_NAME%%-alpine-node:7-slim".

    (...)
    # Setup timezone
     && cp /usr/share/zoneinfo/Europe/Paris /etc/localtime \
     && echo "Europe/Paris" >  /etc/timezone \
     && echo "Europe/Paris" >  /etc/TZ \
     && unset TZ \

If I open a shell (/bin/sh) inside the container, the date is shown in UTC when I type “date”, but if I type “unset TZ”, the date is shown correctly according to the setup timezone.

I don’t have this problem with any of my x86_64 alpine containers.

Ok I’ve found a workaround but maybe it could be improved in an upper layer in one of resin intermediate image (by not setting TZ for example).

“export TZ=Europe/Paris” doesn’t work anywhere.
“unset TZ” works in shell but not in Dockerfile (I have no clue why).
“unset TZ” at the beginning of a startup script (the one in Dockerfile CMD line) works.

UPDATE : I’ve celebrated too soon. “unset TZ” in startup script works only til the end of my startup script. Then if I start a shell in anyway (resin web console or ssh + docker exec) the TZ is set again to UTC.

In a standard Alpine image, this TZ env var is not set, so it should really be this way too in resin alpine images (and UTC will still be the default timezone I guess).

Hey @Tristan107 , What happens if you set TZ as an environment variable for the dashboard? Also it might be worth creating an issue for this on resin.io base images repo here: https://github.com/resin-io-library/base-images

Hi, I’ve tried this out with the original arm32v6/alpine image that we are building on, and it has the same behaviour as the resin/....-alpine images, so it does not come from us, but from upstream.

Looks like the Alpine docs are confusing regarding time zone settings, and lot of out-of date information. The minimum setup I’ve found is installing the tzdata package, and setting the TZ environment variable to the required value, for example in the Dockerfile as below:

...
RUN apk add --no-cache tzdata
ENV TZ=Europe/Paris
...

I’ve compared it to the default x86 container as well, and the difference is that in the ARM images the TZ variable is set by default, while on X86 it is empty (even though there’s a /etc/TZ file in both cases).

This different behaviour between the upstream ARM and x86 images is confirmed by docker inspect:

$ docker inspect arm32v6/alpine:3.6
...
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "TZ=UTC"
            ],
...
$ docker inspect alpine:3.6
...
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
...

So I guess in this case, just have to adapt to the different behaviour, and set the environment variable. (As much as I know there’s no way in Docker at the moment to unset a variable within the Dockerfile…)

(Btw, when there’s no TZ variable set, then the copying to the /etc/localtime as you did should be enough, after which the tzdata package can be uninstalled)

Ok thanks for watching this, I may drop an issue at this docker alpine image, I really thought it was from you since it worked on x86_64 image.

As shown in my example, I’ve already tried :

RUN apk add --no-cache tzdata
ENV TZ=Europe/Paris

and it does not work. /usr/share/zoneinfo is empty if u dont install tzdata, so yes if my /etc/localtime was filled correctly, it’s because tzdata was installed (and it’s uninstalled at the end), so in my opinion, you just can’t adapt to this TZ set to UTC.

Note : since I meet other problems on Alpine, like python gpio library not really ported (not recognized as dependency by some nodes), I’ll just stick with Debian and my huge image (600 Mo vs ~150 Mo on Alpine).

@Tristan107 , yeah alpine does make some things a bit difficult. Depending on what you are doing in your image, you might be able to significantly reduce your debian image size using the new docker mult-stage builds stuff. Something similar to this: https://github.com/resin-io-playground/nodejs-multistage-docker/blob/master/Dockerfile but using debian rather than alpine.

Very strange, I’ve just tried with this little dockerfile:

FROM resin/raspberrypi3-alpine-node:7-slim

RUN apk add --no-cache tzdata
ENV TZ=Europe/Paris

CMD while : ; do date; sleep 5; done

and the output is in the right format:

Tue Jul 18 22:04:32 CEST 2017
Tue Jul 18 22:04:37 CEST 2017
...

In your example you did not install tzdata, hence my details added. If using it like this above does not work, can you share some more info / the project itself, so we can give any more concrete suggestions?

Regarding the time on Alpine, I think you are doing something very similar to this bugreport that wasn’t really a bug. So far as I understand:

  • tzdata package is needed for timezones to be correctly used (timezones other than UTC)
  • There are two ways of setting timezones
    • If using TZ env var or /etc/TZ, then need the tzdata package
    • If there’s no TZ env var set, then can copy the relevant timezone file to /etc/localtime and can remove the tzdata package

So your original example was actually mixing these two methods, as well as have the issue of this base image of TZ already being set, which limits what you can do.

Hope this all is helpful, it’s all pretty much outside of resin, and more related to general Alpine usage and upstream Alpine images.

Ok, I’ll try again quickly then, to finalize this.

Maybe the problem is the uninstallation of tzdata after setup. Or the place of “ENV” before or after the installation of tzdata ?

To further clarify as mentioned things above, based on what I’ve gathered from the Alpine guides and trying it out: if using the TZ env var or the /etc/TZ, then have to keep the tzdata package; if copying the timezone data to /etc/localtime, then can remove tzdata and have to unset the TZ env var, so that doesn’t override the settings.

Yes, except, you can’t “unset” TZ in a Dockerfile script, it doesn’t have effect.

Or maybe if you unset TZ, you have to be sure /etc/TZ is empty too ? I’m trying it right now…

It would make sense since TZ and /etc/TZ are supposed to contain a string refering to a subdirectory of /usr/share/zoneinfo/ (which is filled only if tzdata is installed).

What I have just tested :

  • removing /etc/TZ and unsetting TZ in Dockerfile : /etc/TZ remains empty but something sets TZ back to “UTC” so it doesn’t work (tzdata installed or not installed).

  • When I do exactly like you : not desinstalling tzdata after setup and setting only TZ to Europe/Paris, it works, TZ remains set to Europe/Paris, /etc/TZ is still at “UTC” but is not taken into account, and “date” uses the “Europe/Paris” timezone.

I’m still leaving a note at Docker official images, because they invalidate the basic alpine wiki to set timezone.

https://github.com/gliderlabs/docker-alpine/issues/310

Hello!

When I was using “FROM resin/%%RESIN_MACHINE_NAME%%-buildpack-deps:jessie”, and followed these instructions (https://github.com/resin-io-playground/resin-timezone), everything was fine, the timezone was set to America/Sao_Paulo (which was the one that I specified in a ENV var.

Now, for memory sake, I’m using this base image: “FROM resin/%%RESIN_MACHINE_NAME%%-node:6”, and the time sticks to UTC, ignoring my ENV variable. I thought the base image for node:6 was still debian. Perhaps I’m missing a package that configures the timezone? tzdata is installled as well on the node:6 base image, as I can see from the “dpkg-reconfigure tzdata” command.

EDIT: This link solution solved my problem:

ENV TZ=America/Sao_Paulo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

Hey @arthurmoises, glad it’s working now for you, that’s basically normal Debian behaviour. :slight_smile:

Actually you can also use the following:

ENV TZ=America/Sao_Paulo
RUN echo $TZ > /etc/timezone && dpkg-reconfigure tzdata

because dpkg-reconfigure actually takes the timezone file’s content into account how to set things up, and then you don’t have to mess with the symlinks manually.

1 Like

The issue opened at gliderlabs/docker-alpine is now closed, if you clean your cache on your builders, you will get a fresh arm32v6/alpine image with no “TZ” env var, and the alpine doc for timezone will just work.

2 Likes