Many developers encounter this frustrating scenario: you've explicitly set the timezone in your Docker container through various methods, yet the system still reports UTC time when you run the date
command. Let's dive deep into why this happens and how to properly configure time in containers.
Docker containers inherit their initial time settings from the host machine's kernel, but maintain their own independent time state. The key components affecting time in a Linux container are:
- /etc/timezone (timezone configuration file)
- /etc/localtime (timezone binary data)
- The tzdata package (timezone database)
- The container's running environment variables
Just setting /etc/timezone
isn't enough because:
- The
tzdata
package needs to be properly configured /etc/localtime
needs to be correctly linked- Some applications ignore these files and use environment variables
Here's the proper way to set timezone in a Dockerfile:
FROM ubuntu:trusty
# Install tzdata non-interactively
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y tzdata
# Set timezone
RUN ln -fs /usr/share/zoneinfo/America/Los_Angeles /etc/localtime \
&& echo "America/Los_Angeles" > /etc/timezone \
&& dpkg-reconfigure --frontend noninteractive tzdata
If you need to set timezone at runtime:
Method 1: Environment variables
docker run -e TZ=America/Los_Angeles your_image
Method 2: Volume mounts
docker run -v /usr/share/zoneinfo/America/Los_Angeles:/etc/localtime your_image
After applying these changes, verify with:
docker exec -it your_container date
# Should show: Tue Apr 14 16:46:51 PDT 2015
docker exec -it your_container cat /etc/timezone
# Should show: America/Los_Angeles
If you're still seeing UTC:
- Check if any processes are overwriting TZ environment variable
- Verify no init systems are resetting timezone
- Ensure your application isn't hardcoding UTC
Docker containers inherit their time configuration from the host machine's kernel, but this often leads to UTC being the default regardless of the host's timezone settings. The container's isolated environment doesn't automatically sync with the host's timezone configurations.
Simply modifying /etc/timezone
inside the container often fails because:
- Most base images don't include the full timezone management packages
- The timezone data needs to be properly linked to glibc's time functions
- Some applications bypass system timezone settings and use UTC directly
Here's a proper Dockerfile approach that actually works:
FROM ubuntu:trusty
# Install required packages
RUN apt-get update && apt-get install -y tzdata
# Set timezone (non-interactive)
RUN ln -fs /usr/share/zoneinfo/America/Los_Angeles /etc/localtime && \
dpkg-reconfigure --frontend noninteractive tzdata
# Verify in the same layer
RUN date
For temporary containers or when you can't modify the image:
# Method 1: Mount host time files
docker run -v /etc/localtime:/etc/localtime:ro \
-v /etc/timezone:/etc/timezone:ro \
your_image
# Method 2: Environment variable (for some apps)
docker run -e TZ=America/Los_Angeles your_image
If you still see UTC after these changes:
- Check if your application has its own timezone setting
- Verify the container has the
tzdata
package installed - Test with
date
command directly in the container - Inspect environment variables with
env | grep TZ
For production images, consider this multi-stage approach:
FROM ubuntu:trusty as builder
RUN apt-get update && apt-get install -y tzdata && \
ln -fs /usr/share/zoneinfo/America/Los_Angeles /etc/localtime && \
dpkg-reconfigure --frontend noninteractive tzdata
FROM ubuntu:trusty
COPY --from=builder /etc/localtime /etc/localtime
COPY --from=builder /etc/timezone /etc/timezone
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
# Your application setup continues here