I have a container with a running program inside tomcat. I need to change date only in this container and test my program behaviour. I have time sensitive logic, and sometimes need to see what happens in a few days or months later. Is it possible in docker? I read that if I change date in container, date will get changed on the host system. But it is a bad idea for me. I need to have a few instances of this application on one server and have possibilities of setting up different time for each instance.
But when I try to change date inside the container I get the error:
sudo date 04101812
date: cannot set date: Operation not permitted
Fri Apr 10 18:12:00 UTC 2015
That's not possible with Docker. Docker uses the same clock as the outside kernel. What you need is full virtualization which emulates a complete PC.
The
sudo
fails because it only makes youroot
of the virtual environment inside of the container. This user is not related to the realroot
of the host system (except by name and UID) and it can't do what the realroot
could do.In you use a high level language like Python or Java, you often have hooks where you can simulate a certain system time for tests or you can write code which wraps "get current time from system" and returns what your test requires.
This worked for me, maybe you could try it:
Edit: Execute it inside the container you are having problems. An interface will appear. There you can edit the timezone and localtime for example, and set it correctly, that fixed my problem, that was the same as yours.
Good luck!
I created a Docker image containing libfaketime for use with Alpine but the process can be done in other distributions.
Here's an example of using it Java using Groovy as an example. But Tomcat can be used as well.
Then build and pass the
FAKETIME
environment variable when doing a docker run for exampleSource is in https://github.com/trajano/alpine-libfaketime and the docker image is in https://hub.docker.com/r/trajano/alpine-libfaketime
It is very much possible to dynamically change the time in a Docker container, without effecting the host OS.
The solution is to fake it. 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:
Remember to set the environment variables
LD_PRELOAD
before you run the application you want the faked time applied to.Example:
You can now dynamically change the servers time:
Example:
Yes, i tested it and it work!
use
--privileged
when you runing your imageexample:
For me, I actually needed to set the actual date for testing. I found the following options work on Mac, but you have to realize you'll be changing the date for all of your containers because you're changing the date of the underlying Alpine VM that Docker uses for all of its containers.
OPTION 1: Change the date of your host machine & restart docker
Use this when:
Steps:
Run this sequence again to get back to the right date & time.
OPTION 2: Change the date of the Alpine VM
Use this when:
Steps:
screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
date -s [hh:mm]
control-a :
and typed
To reset the time:
screen -r
ntpd -q
control-a :
and typequit