Docker-alpine: How can I set the timezone please?

Created on 24 Jan 2016  路  19Comments  路  Source: gliderlabs/docker-alpine

I tried many methods, but it still showed UTC. I tried three methods as follows:
1 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2 RUN echo "Asia/Shanghai" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata
3 ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
I wrote these commands in the Dockerfile respectively, none of them did work.
Could you tell me how to set the timezone please? Thanks very much

question

Most helpful comment

# Install base packages
RUN apk update
RUN apk upgrade
RUN apk add ca-certificates && update-ca-certificates
# Change TimeZone
RUN apk add --update tzdata
ENV TZ=America/Bahia
# Clean APK cache
RUN rm -rf /var/cache/apk/*

All 19 comments

I think that first line is correct, but you need to install the "tzdata"
package first.

Thanks, I go to have a try now

Based on the Dockerfile shown it looks like tzdata may have indeed been missing. Please reopen if this is still an issue for you. We _do_ pull in tzdata at build time to specifically grab just the UTC timezone file. So, if that is causing issues this could be considered a bug.

Why does this not work? (Usually people set a soft link, but even copy doesn't do the trick.)

ENV TERM=xterm \
TZ=Europe/Berlin

RUN apk --update add nginx php-fpm php-memcache php-mysqli php-ctype php-zlib tzdata && \
... (some stuff)
cp /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \
apk del tzdata

On the alpine bug list, Christian Kampka advised

docker run -it --rm alpine /bin/sh
/ # date
Sun May 8 20:46:18 UTC 2016
/ # apk add -U tzdata
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/community/x86_64/APKINDEX.tar.gz
(1/1) Installing tzdata (2015g-r0)
Executing busybox-1.24.1-r7.trigger
OK: 8 MiB in 12 packages
/ # cp /usr/share/zoneinfo/Europe/Berlin /etc/localtime
/ # date
Sun May 8 22:46:45 CEST 2016
/ # 

He also said

As a side note, if you want to rely on the TZ environment variable, you cannot remove tzdata, but that should not apply if you set /etc/localtime correctly.

I don't understand this, but after adding _-U_ and substituting TZ in the Dockerfile it works now as intended.

# Install base packages
RUN apk update
RUN apk upgrade
RUN apk add ca-certificates && update-ca-certificates
# Change TimeZone
RUN apk add --update tzdata
ENV TZ=America/Bahia
# Clean APK cache
RUN rm -rf /var/cache/apk/*

Sorry for commenting on a closed issue, but sometimes I just want to deploy a simple application using Docker Compose with some alpine-based containers inside... then I'm forced to override every dockerfile (or use on-the-fly configuration).

TZ variable works for debian-based images, and it's great :-) Why not for alpine?

Even if it's not a bug, would we consider taking it as an usage issue?

After using previous code it started to show current time zone as I understand, but time stays as before.
Wed Nov 1 12:12:45 +06>-6 2017
But real time is 18:12:45. Could someone explain me what this is +06>-6 and how setup time correctly?

@StalkAlex no idea where that +06>-6 is coming from, but the following works fine for me:

$ docker run -it --rm alpine:3.6
/ # apk add --no-cache tzdata
fetch http://dl-cdn.alpinelinux.org/alpine/v3.6/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.6/community/x86_64/APKINDEX.tar.gz
(1/1) Installing tzdata (2017a-r0)
Executing busybox-1.26.2-r7.trigger
OK: 7 MiB in 12 packages
/ # export TZ='America/Los_Angeles'
/ # date
Wed Nov  1 10:09:26 PDT 2017

In a Dockerfile, that would look something like this:

FROM alpine:3.6
RUN apk add --no-cache tzdata
ENV TZ America/Los_Angeles

It's OK in 3.6, but has the described behavior in 3.4, PHP alpine <7.2 is built on it.

> docker run -it alpine:3.4 sh  
/ # date
Thu Nov  2 04:42:58 UTC 2017
/ # export TZ='Asia/Almaty'
/ # date
Thu Nov  2 04:43:10 GMT 2017

Strangely it switches to GMT here (no tzdata installed)?!

/ #  apk add --no-cache tzdata
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/community/x86_64/APKINDEX.tar.gz
(1/1) Installing tzdata (2016d-r0)
Executing busybox-1.24.2-r13.trigger
OK: 8 MiB in 12 packages
/ # date
Thu Nov  2 04:43:33 +06>-6 2017

On the alpine bug list, Christian Kampka advised

docker run -it --rm alpine /bin/sh
/ # date
Sun May 8 20:46:18 UTC 2016
/ # apk add -U tzdata
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/community/x86_64/APKINDEX.tar.gz
(1/1) Installing tzdata (2015g-r0)
Executing busybox-1.24.1-r7.trigger
OK: 8 MiB in 12 packages
/ # cp /usr/share/zoneinfo/Europe/Berlin /etc/localtime
/ # date
Sun May 8 22:46:45 CEST 2016
/ # 

He also said

As a side note, if you want to rely on the TZ environment variable, you cannot remove tzdata, but that should not apply if you set /etc/localtime correctly.

I don't understand this, but after adding _-U_ and substituting TZ in the Dockerfile it works now as intended.

This Work like a charm however, I simply extracted timezone file for my timezone and did COPY mytimezone /etc/localtime without installing tzdata in dockerfile. This also works same, and saves almost ~3MB of container image size.

# Install base packages
RUN apk update
RUN apk upgrade
RUN apk add ca-certificates && update-ca-certificates
# Change TimeZone
RUN apk add --update tzdata
ENV TZ=America/Bahia
# Clean APK cache
RUN rm -rf /var/cache/apk/*

It works, Thank you very much. (Node 12.14.0 Alpine)

As the wiki said:

https://wiki.alpinelinux.org/wiki/Setting_the_timezone

You can now remove the other timezones using "apk del tzdata"

But it doesn't work after "apk del tzdata"

FROM alpine:3.11

ARG TZ='Europe/Brussels'

ENV TZ ${TZ}

RUN apk upgrade --update \
    && apk add -U tzdata \
    && cp /usr/share/zoneinfo/${TZ} /etc/localtime \
    # && ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \
    && echo "${TZ}" > /etc/timezone \
    && apk del tzdata \
    && rm -rf \
    /var/cache/apk/*

CMD ["sh"]
docker build --force-rm -t tz_test .
docker run -it --rm tz_test sh
date

The date is stil UTC datetime.

@kzhui125 If you like to use ENV don't use ENV named TZ.

FROM alpine:3.11

ARG ARG_TZ='Europe/Brussels'

ENV ENV_TZ ${ARG_TZ}

RUN apk upgrade --update \
&& apk add -U tzdata \
&& cp /usr/share/zoneinfo/${ENV_TZ} /etc/localtime \
# && ln -sf /usr/share/zoneinfo/${ENV_TZ} /etc/localtime \
&& echo "${ENV_TZ}" > /etc/timezone \
&& apk del tzdata \
&& rm -rf \
/var/cache/apk/*

CMD ["sh"]

docker build --force-rm -t tz_test .
docker run -it --rm tz_test
date

If you have the timezone configured in the host system you can mount these volumes without installing tzdata

    volumes:
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro

Referring to the previous comment:
Couldn't get that working without having package tzdata in alpine 3.15.3.

Some want to save space or do not have the option to install packages in their use case, so this worked for me and maybe it is helpful for others as well:

  • Install tzdata package
  • Copy the the timezone info of whatever timezone you need (f.e. /usr/share/zoneinfo/Europe/Berlin)
  • Uninstall tzdata
  • Recreate folder /usr/share/zoneinfo/Europe/ (because uninstall deletes it)
  • Place previously copied file back to that dir
    Done. I worked with timezone set in /etc/timezone, but it may also work with timezone set via environment i don't know.
    (Found this out by analysing the "date" call with strace)

Referring to the previous comment:
Couldn't get that working without having package tzdata in alpine 3.15.3.

Some want to save space or do not have the option to install packages in their use case, so this worked for me and maybe it is helpful for others as well:

  • Install tzdata package
  • Copy the the timezone info of whatever timezone you need (f.e. /usr/share/zoneinfo/Europe/Berlin)
  • Uninstall tzdata
  • Recreate folder /usr/share/zoneinfo/Europe/ (because uninstall deletes it)
  • Place previously copied file back to that dir
    Done. I worked with timezone set in /etc/timezone, but it may also work with timezone set via environment i don't know.
    (Found this out by analysing the "date" call with strace)

/ # cat /etc/timezone Europe/Bucharest

the date command still shows UTC

@mihalycsaba Tried again, looks like i had TZ also set, sorry to have confused you. This works for me:

$ cat Dockerfile
FROM alpine:latest
ENV TZ="Europe/Berlin"
RUN apk add tzdata && cp /usr/share/zoneinfo/Europe/Berlin /tmp && apk del tzdata && mkdir -p /usr/share/zoneinfo/Europe/ && cp /tmp/Berlin /usr/share/zoneinfo/Europe/ && echo "Europe/Berlin" > /etc/timezone
$ docker build -t tztest:latest .
[...]
$ docker run -it --rm tztest:latest sh
/ # date
Thu Jun  3 17:09:30 CEST 2021
/ #

Fucking hell lets end the suffer now and forever here is my solution to this simple but teethgrinding problem:

RUN apk add --no-cache tzdata
ENV TZ=Europe/Berlin
RUN cp /usr/share/zoneinfo/$TZ /etc/localtime
Was this page helpful?
0 / 5 - 0 ratings