When you use Docker & PHP, you can set timezone to many places.
php.ini
example
[Date] date.timezone = "Europe/Madrid"
Dockerfile
example
FROM php:8.1.12-fpm ENV TZ=America/Los_Angeles
docker-compose.yml
example
php: container_name: php build: ./containers/php volumes: - ./src:/var/www/src:cached working_dir: /var/www/src environment: TZ: Asia/Tokyo
It depends on project where the value is set.
I wondered what is the most prioritized timezone setting if I set all of places differently.
Here is a source code that I used to research.
<?php $defaultTimezone = date_default_timezone_get(); var_dump( $defaultTimezone );
1. define 3 places, php.ini, Dockerfile and docker-compose.yml
Result.
string(13) "Europe/Madrid"
Dockerfile and docker-compose.yml definitions were ignored and php.ini definition was reflected.
It seems like php.ini definition is the most prioritized.
Next, remove php.ini definition and execute.
2. define 2 places Dockerfile and docker-compose.yml
Result.
string(3) "UTC"
Why? UTC appeared which is not defined anywhere.
So, I checked OS timezone setting.
$ timedatect bash: timedatect: command not found $ echo $TZ Asia/Tokyo $ cat /etc/timezone Etc/UTC
Each command showed different result such as "Asia/Tokyo" and "Etc/UTC". It is a bit confusing.
After researching I found out that timezone setting will not be reflected to PHP setting only by defining environment valuable "TZ" in Dockerfile.
If you want to use OS timezone, you have to define in tzone.ini.
So, I edited Dockerfile.
ENV TZ=Asia/Tokyo RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN printf '[Date]\ndate.timezone="%s"\n', $TZ > /usr/local/etc/php/conf.d/tzone.ini
Then, the result of PHP code execution, timezone setting in Dockerfile is reflected.
string(19) "America/Los_Angeles"
/etc/timezone will be updated.
$ cat /etc/timezone America/Los_Angeles
3. define 1 places docker-compose.yml
Result.
string(3) "UTC"
The result is same as I expected because tzone.ini is not set.
Just in case, check OS timezone setting.
$ timedatect bash: timedatect: command not found $ echo $TZ Asia/Tokyo $ cat /etc/timezone Etc/UTC
It is not practical to define the setting in docker-compose.yml as section "2", so, if you need to set timezone, you should set in other places.
Sometimes I found timezone setting as "TZ: UTC" in docker-compose.yml, this setting may not be working, but actually default timezone setting is working.
However, you can reflect timezone setting of docker-compose.yml by stating as below in php.ini.
[Date] date.timezone = ${TZ}
(note) It is necessary to set php.ini in the container.
Then, the timezone setting of docker-compose.yml is reflected.
Here is the result.
string(10) "Asia/Tokyo"
Summary
- Timezone of Dockerfile reflects to only OS but not to PHP. It is necessary to set tzone.ini.
- It is too much work, I personally recommend to set timezone in php.ini.
- If you want timezone as variable, set docker-compose.yml and pass to php.ini.
When you face to such a situation "Where is the timezone set in this project?", I recommend check "php.ini" first, after that "docker-compose.yml" lastly "Dockerfile".
Extra
You can overwrite timezone using "date_default_timezone_set".
<?php date_default_timezone_set('Australia/Sydney'); $defaultTimezone = date_default_timezone_get(); var_dump( $defaultTimezone );
Result.
string(16) "Australia/Sydney"
Top comments (2)
Thanks for the write up for such a niche problem such as this one!
Thanks for the comment!
You're right — it's a niche issue, but it can sometimes cause confusion when analyzing source code.
That's why I ran some experiments and organized the information, then turned it into a blog post.
I'm glad to hear it was helpful for you!