5

I have been working through setting my ms-sql docker container to use the Linux host date time settings. I'm using a docker-compose file, and for the most part the solution appears to be to map volumes like so (references: Bobcares, SO ):

volume:
  - /etc/timezone:/etc/timezone:ro
  - /etc/localtime:/etc/localtime:ro

At first glance, this looks fine. I can check what date the container thinks it is, and it reflects the host local time zone. The SQL instance, however, is still displaying UTC time for GetDate().

There is a symbolic link within the container though, that always looks like this: localtime -> /usr/share/zoneinfo/Etc/UTC. This is not what I am expecting based on the volume mapping, as it is different from the host localtime -> ../usr/share/zoneinfo/Australia/Sydney. I can manually update this link within the container and GetDate() on SQL returns the correct local datetime. All is lost on a docker-compose down, as expected.

I need this to persist across container restarts, and I want to use the volume from the docker-compose file to handle time zones as we deploy to multiple time zones. I'm sure the problem is my noob linux skillset, so happy for advice on how to improve this. How do I fix the symbolic link problem (if that is indeed the root cause of the problem)?

Host is: Ubuntu 20.04.1 LTS (Focal Fossa) ms-sql image is: mcr.microsoft.com/mssql/server:2019-latest

Damo
  • 197
  • 1
  • 2
  • 10

2 Answers2

6

I kept searching and I found the answer in this post.

Full steps I needed:

  • Set timezone of host
  • add TZ enviroment variable to docker-compose.yml
  • add volume mapping for host time zone to docker-compose.yml

My docker-conpose section for ms-sql now looks like this (some parts omitted for brevity):

ms-sql-server:
  image: damo/sqlexpress:1.0.1
  ports: 
    - "14333:1433"
  volumes: 
    - sqldata:/var/opt/mssql
    - /etc/timezone:/etc/timezone:ro
    - /etc/localtime:/etc/localtime:ro
  restart: unless-stopped

The only change I need to make between deployments is the environment variable.

Nam G VU
  • 33,193
  • 69
  • 233
  • 372
Damo
  • 197
  • 1
  • 2
  • 10
4

In my case adding this to Dockerfile works and changes every image I build or run:

FROM ubuntu:20.04 # or any other distro
ENV TZ=Asia/Tehran
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
Saeed
  • 3,255
  • 4
  • 17
  • 36
  • 1
    Does this lock the image to the time zone, though? I’m trying to avoid creating a new image for every time zone. – Damo Jun 04 '21 at 07:45
  • 1
    Yes, since your image is built with Tehran time zone as in my example, so every time I run my image and run `date` command, I see my current local time (now it is 12:34 P.M.). By avoiding creating new image for every time zone, you mean IMAGE_A should be in Tehran, IMAGE_B in New York, etc.? Or all images should in in Tehran? – Saeed Jun 04 '21 at 08:04
  • 1
    I have an mssql image that is UTC by default. I use docker-compose to run up multiple containers of which mssql is but one. I am deploying to 4 different time zones right now and I want to keep the same mssql image, but make that image use the local time zone - the hosts time zone - not UTC. If the container is in Sydney, I want mssql to use Sydney time (+10). If it is in Perth, I want the container to use Perth time (+8). – Damo Jun 04 '21 at 10:11