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:roSee 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": unknownNo 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": unknownSimple 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"