vscode-dev-containers icon indicating copy to clipboard operation
vscode-dev-containers copied to clipboard

Support setting container time zone to host time zone

Open aaronadamsCA opened this issue 5 years ago • 12 comments

It might be good to support and/or document a first-class way to build dev containers that use the host machine's time zone instead of UTC.

While it's far from a showstopper, right now Git commits made inside a container are recorded in UTC. It's a bit odd to look at git log and see mixed time zones on my own commits depending on whether they came from GitHub (local time) or the dev container (UTC).

This also means I can't use git config log.date default-local to tell git log to print all times in local time (unless I also alias git='TZ=America/Toronto git').

Hard-coding a time zone into .devcontainer/Dockerfile should work for me, but probably isn't a great solution for larger projects.

aaronadamsCA avatar Apr 29 '20 05:04 aaronadamsCA

Thanks for the suggestion! This should be doable by using the "initalizeCommand" property to get the local timezone into a file that is then pulled into the container via the Dockerfile (or even "postCreateCommand"). I'll look into documenting it.

Chuxel avatar Apr 29 '20 14:04 Chuxel

Any update?

LorhanSohaky avatar Aug 26 '21 02:08 LorhanSohaky

Also curious to see what's the most crossplatform way of doing this short of exposing a build arg to override the timezone.

darkvertex avatar Nov 01 '21 21:11 darkvertex

I've worked around the problem with the following code snippets

In Dockerfile

RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
    && apt-get install -y locales locales-all

In devcontainer

"containerEnv": {
		"LC_ALL": "pt_BR.UTF-8",
		"LANG": "pt_BR.UTF-8",
		"LANGUAGE": "pt_BR.UTF-8"
	},

LorhanSohaky avatar Nov 03 '21 03:11 LorhanSohaky

Did that actually affect your time zone?

Those env vars are normally for "localization" (system language, date format style, decimal separator character, etc.), not for time zones.

darkvertex avatar Nov 03 '21 03:11 darkvertex

Did that actually affect your time zone?

Those env vars are normally for "localization" (system language, date format style, decimal separator character, etc.), not for time zones.

You're right, this was to solve an encoding problem

LorhanSohaky avatar Nov 04 '21 22:11 LorhanSohaky

This is an old issue, but to set the system time zone, do two things:

  1. Install the tzdata package if its not already in your image.
  2. Use containerEnv in devcontainer.json to set the TZ environment variable if you're using an image or Dockerfile
    • Or use your Docker Compose to set the env var for that scenario.
    • Or if you prefer to have this set for everyone in your Dockerfile, use ENV TZ="<timezone>" in the Dockerfile.

e.g.

"containerEnv": { "TZ": "America/Chicago" }

or in a Dockerfile

ENV TZ="America/Chicago"

Run ls /usr/share/zoneinfo to see available timezones.

What is not available is automatically setting this value based on the host's machine with no work.

Chuxel avatar May 09 '22 19:05 Chuxel

Here's what I do, that works well for my use case:

In devcontainer.json, add a mount like this: "type=bind,readonly,source=/etc/localtime,target=/etc/localtime",

daulis avatar Dec 16 '22 20:12 daulis

Here's what I do, that works well for my use case:

In devcontainer.json, add a mount like this: "type=bind,readonly,source=/etc/localtime,target=/etc/localtime",

This works for me on MacOS, but the actual behaviour is very unexpected!

/etc/localtime is a symbolic link both locally (to /var/db/timezone/zoneinfo/Europe/Zagreb) and in the dev container (/usr/share/zoneinfo/Etc/UTC).

The bind mount follows both symlinks, mounting /var/db/timezone/zoneinfo/Europe/Zagreb at /usr/share/zoneinfo/Etc/UTC:

$ zdump /usr/share/zoneinfo/Etc/UTC
/usr/share/zoneinfo/Etc/UTC  Fri Dec 30 09:43:22 2022 CET

I'm not sure what other side effects this could have, but for MacOS and Linux users it might be a good enough workaround.

aaronadamsCA avatar Dec 30 '22 09:12 aaronadamsCA

I tried the mount solution on MacOS, and while this worked for the date command on the shell, in Node.js Intl.DateTimeFormat().resolvedOptions().timeZone would still equal "UTC". But, if I add the following line to the Dockerfile

RUN ln -sf /usr/share/zoneinfo/Australia/Sydney /etc/localtime

then Intl.DateTimeFormat().resolvedOptions().timeZone equals "Australia/Sydney"

tompahoward avatar Jan 17 '23 22:01 tompahoward

Here's the workaround I'm using. In devcontainer.json add a TZ build arg that uses the local TZ and if not set a default. e.g.

	"build": {
		"dockerfile": "Dockerfile",
		"args": { "TZ": "${localEnv:TZ:Australia/Sydney}" }
	}

In the Dockerfile add the following lines

ARG TZ
ENV TZ="$TZ"

This will default the TZ to the specified default, but allow users to override it by setting the TZ env variable on the host machine.

From the container

node ➜ /workspaces/ArchitectureDoc (main) $ date
Wed 18 Jan 2023 09:58:56 AM AEDT
node ➜ /workspaces/ArchitectureDoc (main) $ node
Welcome to Node.js v16.19.0.
Type ".help" for more information.
> Intl.DateTimeFormat().resolvedOptions().timeZone
'Australia/Sydney'
> 

tompahoward avatar Jan 17 '23 23:01 tompahoward

For people who are still trying to figure this out, I combined this in the mounts section of the devcontainer.json:

"source=/etc/localtime,target=/usr/share/zoneinfo/hostlocaltime,type=bind,readonly"

with this in the Dockerfile:

RUN ln -sf /usr/share/zoneinfo/hostlocaltime /etc/localtime

The idea is that the mount follows the symbolic link on the host system, but maps it to a known location in the container with the other time zones. Then, you can create a symbolic link to the host time zone like you would to set it to any other timezone.

iownbey avatar Jul 17 '23 16:07 iownbey