Manipulating Time Inside a Docker Container

Home, Bangkok, Thailand, 2020-08-27 21:48 +0700

#software_engineering

 
Photo by Jon Tyson

I had an edge case where I needed to be able to run a Docker container with the time 24 hours ahead of the real time for a single containerized build agent in my TeamCity build farm.

It’s not really possible to do this under normal circumstances because containers are just isolated processes sharing the same machine. But there is a solution - libfaketime. You can use LD_PRELOAD to load libfaketime in ahead of the normal system libraries so that it can intercept date/time system calls and returns a time that is adjusted by your preferred offset. This can be done with containers or normal processes.

It was quite easy to bake this into a Docker image - here’s a minimal sample Dockerfile which uses a multi-stage build to keep the build tools and sources out of the final image:

FROM debian:10.5 as builder

RUN apt-get update && apt-get install -y make gcc git

# Get the sources and checkout at stable release 0.98
# see https://github.com/wolfcw/libfaketime/releases
RUN git clone https://github.com/wolfcw/libfaketime.git && \
    cd libfaketime && \
    git checkout dc2ae5eef31c7a64ce3a976487d8e57d50b8d594 && \
    make

FROM debian:10.5 as final

COPY --from=builder /libfaketime/src/libfaketime.so.1 /usr/local/lib
ENV LD_PRELOAD=/usr/local/lib/libfaketime.so.1
ENV FAKETIME="+2d"

Build it with:

$ sudo docker build --target final -t my/faketime .

When a container is launched from this image it will appear to have a date/time exactly 2 days ahead of the real time as reflected by the host’s clock:

$ date
Thu Aug 27 12:08:38 UTC 2020

$ sudo docker run --rm -it my/faketime date
Thu Aug 29 12:08:45 UTC 2020

I’ve baked a +2 day clock offset into this image with an ENV directive but you can also just specify FAKETIME when launching the container:

$ sudo docker run --rm -it --env FAKETIME=+9d my/faketime date
Sat Sep 05 12:08:57 UTC 2020

libfaketime also supports other options like setting the absolute time rather than specifying an offset - see section 4 of the README docs.

libfaketime - a pretty cool solution if you have one of these edge cases. It nicely solved my TeamCity build agent requirement.