28

Is there any way to set a Docker containers system time dynamically (at run time) without effecting the host machine?

Using

hwclock --set --date "Sat Aug 17 08:31:24 PDT 2016"

gives the following error:

hwclock: Cannot access the Hardware Clock via any known method.
hwclock: Use the --debug option to see the details of our search for an access method.

Using

date -s "2 OCT 2006 18:00:00"

gives the following error:

date: cannot set date: Operation not permitted

Use case:

I need to test time sensitive software (behaviour depends on the date).

Other common use cases:

  • running legacy software with y2k bugs
  • testing software for year-2038 compliance
  • debugging time-related issues, such as expired SSL certificates
  • running software which ceases to run outside a certain timeframe
  • deterministic build processes.
21

It is possible

The solution is to fake it in the container. This lib intercepts all system call programs use to retrieve the current time and date.

The implementation is easy. Add functionality to your Dockerfile as appropriate:

WORKDIR /
RUN git clone https://github.com/wolfcw/libfaketime.git
WORKDIR /libfaketime/src
RUN make install

Remember to set the environment variables LD_PRELOAD before you run the application you want the faked time applied to.

Example:

CMD ["/bin/sh", "-c", "LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME_NO_CACHE=1 python /srv/intercept/manage.py runserver 0.0.0.0:3000]

You can now dynamically change the servers time:

Example:

import os
def set_time(request):
    print(datetime.today())
    os.environ["FAKETIME"] = "2020-01-01"  # Note: time of type string must be in the format "YYYY-MM-DD hh:mm:ss" or "+15d"
    print(datetime.today())
  • 6
    For others coming to this solution, be aware that this will not work for golang applications or other statically linked exes. – Sentinel Oct 16 '18 at 11:38
  • 5
    Thanks @Sentinel. Funnily enough, I just found this answer via google, I specifically want to use it with a golang app, and I noticed that you left this comment on a 1.5-years-old question just 2 hours ago. Feels like it was for me. Thanks! :) – dimonomid Oct 16 '18 at 13:42
  • Why does is not work in your situation? Does Golang not use system calls to retrieve time? @dimonomid I suggest you give it a try, it’s quick to implement the solution. – Vingtoft Oct 16 '18 at 14:02
  • 1
    @Vingtoft Let me know if it does in fact work, but search around. Golang doesn't dynamically link in the libraries. – Sentinel Oct 16 '18 at 16:06
  • 1
    @dimonomid Yeah I was pretty disappointed. More disappointed with Docker actually. I need to implement timing related tests. This makes Docker pretty much useless as a "container". I would have thought intercepting system time calls for timezone sync would have been item 1 on the Docker agenda. Apparently not. – Sentinel Oct 16 '18 at 16:07
4

Jenny D is correct in that by default Docker container doesn't allow access to system clock.

However, on Linux, if you're fine with your container having access to this capability, you can allow this capability using "--cap-add=SYS_TIME" option of "docker run" command when creating you container:

# docker run --cap-add=SYS_TIME -d --name teamcity-server-instance -v /opt/teamcity/data:/data/teamcity_server/datadir -v /opt/teamcity/logs:/opt/teamcity/logs -p 80:8111 jetbrains/teamcity-server

Then, you can change the time from inside the running container:

# docker exec -it teamcity-server-instance /bin/bash
# date +%T -s "15:03:00"
15:03:00
#

Reference documentation: https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities

  • 2
    This changes the time on the host machine. Time on a Linux system is not currently namespaced, there's only one value for the host and all containers. – BMitch Feb 27 '18 at 12:17
  • Yes, you're right. This changes the time of the host machine clock. Just re-read the question and realized the question, indeed, explicitly mentioned about NOT changing the clock of the host machine. I stand corrected :) – Oleg Kazakov Feb 27 '18 at 22:50
0

Start the container with an additional environment variable:

docker run -e "SET_CONTAINER_TIMEZONE=true" \
           -e "CONTAINER_TIMEZONE=US/Arizona" [docker image name]
  • Im looking for a way to set the time dynamically, meaning it can be set at runtime. I have updated my question. – Vingtoft Jan 6 '17 at 13:14
0

docker-compose solution:

Add /etc/localtime:/etc/localtime:ro to the volumes attribute.

Look at to this link for an example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.