Use the Dev Container Feature ghcr.io/hwaien/devcontainer-features/match-host-time-zone to make a Dev Container’s time zone match the host’s time zone.

Containers isolate time zone tracking

For those unfamiliar: Dev Containers are a smooth way for software developers to maintain consistent development environments. Dev Containers are built on top of industry standard container formats and runtimes.

An essential feature of containers is file system isolation. A container’s file system is virtually isolated from the host’s file system. (This is done using the pivot_root system call to mount a separate root file system for the container, and using the mount namespaces feature to keep the container’s directory hierarchy isolated.)

As a consequence of file system isolation, any file-based operation inside a container will behave independently of the host system. This includes keeping track of time zone, which is done based on the file /etc/localtime.

Time zone matters in software development

A Dev Container’s /etc/localtime is set to a fixed time zone when its image was built. For many Dev Containers, this time zone is UTC±00:00. This means that Dev Containers usually come with a time zone that is different from the developer’s local time zone.

This is unfortunate, as time zone matters in software development. Computer software components typically log significant events during their operations. The logs include timestamps to clarify the temporal order of events. Software developers use these logs to either confirm the correctness of software functions or troubleshoot software errors.

Troubleshooting software errors is not an easy task. Having event timestamps logged in a time zone that is different from the developer’s local time zone only makes the troubleshooting task more complicated and mistakes more likely.

Match container time zone with host

Recognizing the significance of time zones, some container management tools provide direct support to match a container’s time zone with its host’s time zone. For example, the run command of Podman supports a --tz=local configuration to set a container’s time zone to match the host machine.

If you use Podman for containerization, thats the end of the story. If you run VS Code Dev Containers on Docker Desktop, you will discover that Docker’s run command does not provide the same support. To achieve the same result, you need to use a bind mount to mount the host’s /etc/localtime at the same location in the container. The devcontainer.json Dev Container metadata syntax to specify this bind mount is as follows.

{
  ...
  "mounts": [
    ...
    {
      "source": "/etc/localtime",
      "target": "/etc/localtime",
      "type": "bind"
    }
  ]
}

Use Dev Container Feature to share configuration

I work with many source code repositories, and I find it repetitive to duplicate the bind mount metadata. It violates the DRY principle of software development. Therefore, I created the match-host-time-zone Dev Container Feature to maintain the mount configuration in a central location. Dev Container Features are self-contained, shareable units of configuration for Dev Containers. There are at least two different ways to use the match-host-time-zone Feature.

Firstly, if you would like all developers working on your repository to share the time zone matching behavior, reference the match-host-time-zone Feature in the repository’s devcontainer.json file like this:

{
  ...
  "features": {
    ...
    "ghcr.io/hwaien/devcontainer-features/match-host-time-zone": {}
  }
}

Otherwise, if you do not want to force the Feature onto others, but want all your own Dev Containers to match host time zone, edit your VS Code settings.json like this:

{
  ...
  "dev.containers.defaultFeatures": {
    ...
    "ghcr.io/hwaien/devcontainer-features/match-host-time-zone": {}
  }
}

Further Reading