Docker Tips: Synchronize Container Timezone with Host Machine via Docker-Compose in Ubuntu 18.04

The true story of pain…

During composing several containers I found a need to synchronize the timezone for some of them with host machine. Because of I wished to create general-purpose image and tune it settings during the run process I decided to perform respective actions via docker-compose.yml.

The first recommendation found in the Web didn’t give any profit: map container file /etc/localtime to local file /etc/localtime by adding this directive in the docker-compose.yaml

services:
my_service:
...
volumes:
...
- /etc/localtime:/etc/localtime:ro

See the difference after running docker-compose up:

dockeradmin@dockerhost:~/my_service$ ls -l /etc/localtime
lrwxrwxrwx 1 root root 31 Nov 2 16:30 /etc/localtime -> /usr/share/zoneinfo/Europe/Moscow
dockeradmin@dockerhost:~/my_service$ docker exec -it my_service /bin/bash -c “ls -l /etc/localtime”
lrwxrwxrwx 1 root root 27 Nov 4 11:43 /etc/localtime -> /usr/share/zoneinfo/Etc/UTC
dockeradmin@dockerhost:~/my_service$

The second recommendation found on the Web didn’t get any profit in more sophisticated way… In this case some guys recommended add next command to docker-compose.yml

services:
my_service:
...
command:
- /bin/bash -c "ln -snf /usr/share/zoneinfo/$$TZ /etc/localtime && dpkg-reconfigure -f noninteractive tzdata"

What did I see after running docker-compose up:

ERROR: for 21844dd33556_my_service  Cannot start service my_service: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \"/bin/bash -c \\\"ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && dpkg-reconfigure -f noninteractive tzdata\\\"\": stat /bin/bash -c \"ln -snf /usr/share/zoneinfo/$TZ /etc/timezone && dpkg-reconfigure -f noninteractive tzdata\": no such file or directory": unknown

No such file or directory… After several debugging and searching iterations I decided to check if the command directive will run any binary in my container:

services:
my_service:
...
command:
- /bin/bash -c "echo Hello world"

And this is the result of running docker-compose up:

ERROR: for 21844dd33556_my_service  Cannot start service my_service: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \"/bin/bash -c \\\"echo Hello world\\\"\": stat /bin/bash -c \"echo Hello world\": no such file or directory": unknown

Simple echo command was not run inside the container… After several addition hours of debugging I found this thread in the Docker-Compose github. I’ll just put the most significant posts here:

So four years there is only two ways to solve this (and similar) task:

  • you can do it via Dockerfile and receive less general-purpose image (and build differ images for every piece of task!);
  • you can write bash script to execute some docker exec commands after container creation (so you need two tools against one docker-compose).

And my final solution was to write this bash script:

#!/bin/bash
###################################################
# Run containers #
###################################################
docker-compose up -d
###################################################
# Set timezone #
###################################################
docker exec -it container1 /bin/bash -c "ln -snf /usr/share/zoneinfo/Europe/Moscow /etc/localtime && dpkg-reconfigure -f noninteractive tzdata"
docker exec -it container2 /bin/bash -c "ln -snf /usr/share/zoneinfo/Europe/Moscow /etc/localtime && dpkg-reconfigure -f noninteractive tzdata"
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade