47

I have a docker-compose file running a few Dockerfiles to create my containers. I don't want to edit my Dockerfiles to set timezones because they could change at any time by members of my team and I have a docker-compose.override.yml file to make local environment changes. However, one of my containers (a Selenium based one) seems to not pull host time zone and that causes problems for me. Based on that I want to enforce timezones on all my containers. In my Dockerfiles right now I do

ENV TZ=America/Denver
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

And everything works fine. How do I replicate the same command in docker-compose syntax?

Ben Nelson
  • 7,174
  • 10
  • 52
  • 89

5 Answers5

48

This is simple solution:

environment:
  - TZ=America/Denver
MxWild
  • 2,280
  • 1
  • 12
  • 13
46
version "2"

services:
  serviceA:
    ...
    environment:
      TZ: "America/Denver"
    command: >
      sh -c "ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && 
      echo $TZ > /etc/timezone &&
      exec my-main-application"

Edit: The question didn't ask for it but I've just added exec my-main-application to show how the main process would be specified. exec is important here to make sure that my-main-application receives Ctrl-C (SIGINT/SIGKILL).

Bernard
  • 14,187
  • 11
  • 62
  • 62
  • 1
    Keep in mind that docker-compose's "command" overrides the default command, if any. Reference: https://docs.docker.com/compose/compose-file/#/command – Claudio d'Angelis Dec 22 '16 at 09:23
  • 1
    @Claudiod'Angelis That's correct, and that's also the desired behaviour here. On quick review of my code I realised that I need to specify how the main process for the container is started. Adding it now. – Bernard Dec 23 '16 at 00:22
  • what do I put for `my-main-application`? where does it take this name from? service name? name of dll? – lenny Jan 07 '19 at 16:45
  • @lennyy It's the name of your main executable inside your container. Add the path if it can't find it. – Bernard Jan 08 '19 at 01:15
  • @Alkaline So my `dockerfile` that was generated by VS for the docker project contains `ENTRYPOINT ["dotnet", "vote-server.dll"]`. would my `docker-compose` command therefore be `command: > sh -c "ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && exec dotnet vote-server.dll"`? also, whenever I have a command in my docker-compose it won't start with the message that it can't find the server's container... I suppose it's because the command doesn't start the actual program, the container crashes and when it tries to work with it, its gone – lenny Jan 08 '19 at 08:24
  • If you have an ENTRYPOINT defined, then the `command` is passed as argument to the ENTRYPOINT executable. Not what you want here. To make it simpler here, just redefine `entrypoint: []` and only use `command:` as you wrote it above. See https://medium.freecodecamp.org/docker-entrypoint-cmd-dockerfile-best-practices-abc591c30e21 for the explanation. – Bernard Jan 17 '19 at 09:09
24

The easiest solution would be share volume in docker-compose.yml like this

ipchanger:
  image: codertarasvaskiv/ipchanger:raspberry
  volumes:
    - "/etc/localtime:/etc/localtime:ro"
  • ro - means container can only read from /etc/localtime of host-machine.
Taras Vaskiv
  • 1,849
  • 14
  • 15
  • While ive seen comment that this doesnt always work, it worked for my container. – Hayden Thring Dec 13 '21 at 03:38
  • Unfortunately, this does not work on musl-libc based docker images, like some Alpine ones. Just tried it on homeassistant. They purposefully only support the TZ method. – FredG Mar 08 '22 at 09:54
9
version: '3.6'
services:
  mysql:
    image: mysql:5.6
    restart: always
    container_name: dev-mysql
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    restart: always
    environment:
     - TZ=Asia/Shanghai
     - MYSQL_ROOT_PASSWORD=password # set the root password
    ports:
      - '3306:3306'
    volumes:
      - "/etc/localtime:/etc/localtime:ro"
      - "/etc/timezone:/etc/timezone:ro"

This my docker-compose.yaml of mysql

Reminder,you need recreate container,other than restart. if you change the yaml need to recreate

docker-compose -f docker-compose.yaml stop
docker-compose -f docker-compose.yaml rm
docker-compose -f docker-compose.yaml start
ty4z2008
  • 290
  • 3
  • 7
-1
 version: '2'
 services:
   ServiceA:
     image: image:
   - '/etc/localtime:/etc/localtime:ro'
Mugeesh Husain
  • 171
  • 1
  • 12