Category Archives: DevOps

Keeping timezone data current

On 1st of November 2026 several canadian provinces will not fall back to standard time from DST. They decided at several different points in time that they will not do so.

British Columbia did so in March already whereas Alberta decided so in June, the Northwest Territories in August and Manitoba in September.

As is the usual process shortly after the decission was made, there was a new version of the timezone-database released so that the information is available only with a short delay to everyone that needs it.

Who needs that? Well… That database is on every computer whether Linux, Windows or MacOS, on every mobile device from Android to iOS and on every Smartwatch out there. In every GPS in your car, yacht or plane. More or less in any electronic device that keeps track of time. So yes! Your smart-fridge might also be running it.

I was now recently challenged to do some updates of data that was converted wrongly based on the information in the old versions of the database and to convert it to the new version of the database (I have written why it is a bad idea to do that previously)

Only to end up in its own kind of hell.

It all started with something that I realized quite some time back: The International Components for Internationalization – in Short ICU – ship with their own version of the timezone database. And the ICU version in some linux-distributions is notorioulsy outdated. And due to the ICU version being outdated, the timezone-data is also outdated. Not by a month or one or two versions. We are talking years. The probably still widely used Ubuntu LTS version 24.04 – codename Noble Numbat – ships with ICU version 74.2 – released in December 2023. And that ships with the timezone database 2023c from March 2023.

When I realized that, I started digging into how to update the ICU version so that PHP applications can actually get the latest ICU as well as the latest timezone-data.

And then I had to dig into that deeper. And I figured out that it is much easier to do the updates for the ICU timezone-data (not the update of the ICU package itself though! Just the timezone-data!) by installing a package called tzdata-icu!

Install that on your ubuntu machine and you are up-to-date! (Sidenote: Why that package is not automatically installed when installing the ICU package is totally beyond me! Why would one want to use the ICU package that is aweseome for date-formatting but use the outdated timezone information for that?)

Or so I thought…

It turned out that the release of the timezone-database does not mean that there will be a corresponding release of the tzdata-package (or the tzdata-icu package) in Ubuntu. That can take a while. And when it is available it is first available in the proposed channel and then some days later moves to the update channel…

It looked like the tzdata package of Ubuntu for the tzdb release 2026b was released in the update channel in July. Remember: The release of the tzdb was in March.

So. Looks like everything is solved.

Finally I had everything up-to-date. Slightly delayed due to the package-delay, but still!

Along came GithubActions.

Where I installed php running on an Ubuntu system.

And suddenly all my tests that require the latest timezone data failed. Looks like the Ubuntu runner used outdated data

So then… Luckily Derick Rethans maintains the timezonedb package on pecl and that is usually available for PHP with a very short delay! So I installed setup-php with extension: timezonedb and everything was good. (I actually had to use timezonedb-2026.5 but that was due to a bug that should be fixed with the next release!)

What did I learn from this:

  • Just because ther eis a new release of the IANA timezone database doesn’T mean that there is immediately a new release for my distribution
  • The ICU extension uses its own timezone database. And by default a really old one
  • The timezonedb extension for PHP is usually really up-to-date and a safe way to update the timezones for PHP.
  • Updating the timezones for ICU can be really easy depending on the distro
  • The challenge is not creating code that works correctly with timezones. It’s getting the correct data on time.

Code-Coverage with PCOV in a mono-repo

Today I finally managed to find and fix an issue that we had for some time with Code-Coverage generation with PCOV in github actions.

To give you a bit of background, imagine a project that uses 2 separate folders where one contains the business-logic and one contains the framework-related code. The framework-related part contains a lot of integration and end-to-end test that – of course – also use and therefore test the business-logic.

Every PullRequest runs the tests both from the bunsiness-logic part as well as from the framework-related part. And to give the developers feedback how well the changed code is covered with tests we collect coverage data and generate a patch-coverage report. I wrote about that some time back. So we now get a comment each in the PR that contains the untested lines in the business-logic related part and the framework-related part respectively.

That worked flawlessly for the business-logic related part as those were mostly unit-tests that do not rely upon the framework-related code.

The framework-related part though didn’t work that great. It always showed the business-logic related parts as untested even though I knew they were tested.

Continue reading Code-Coverage with PCOV in a mono-repo →

Deploy using git archive

When deploying code I by now almost always use git archive for that no matter whether that is library code or actually product code that gets deployed onto a (web)server.

Recently I had a chat with someone that so far hadn’t heard of that so I realized perhaps it’s time to write about it.

What is it

git archive is a tool that exports the content of a git repository into an archive file. But while doing so it also uses information in a .gitattributes file to decide whether to include a file into the archive or not and also whether to modify a file.

A lot of people already know about the .gitattributes file as it makes sure that certain files are removed from the archive that is created by github when creating a release.

The documentation for .gitattributes has (amongst a huge number of other information and awesome things that can be done via that file – but that’s for some other time) a special part about creating archives that talks about two attributes:

Continue reading Deploy using git archive →

ICU in PHP-images from Docker-Hub

Recently I was preparing a talk for the fwdays PHP in Kyiv. A talk about internationalization. And gues what: One of the parts of internationalization is: Timezones. Yes, I know, I am fond of them and all but that’s not what this is going to be about.

In the talk I am showing how to propperly render a datetime for a given locale in a given timezone using the IntlDateFormatter. As the talk will be in Kyiv I thought it’s only fair to use the Europe/Kyiv timezone.

The timezone Europe/Kyiv is a rather new one and was introduced in 2022 when the former timezone Europe/Kiev was renamed to Europe/Kyiv as that by now was the more widely used international spelling of the Ukrainian capital (Thank you, Vladimir, for making the world aware that the russian transcription isn’t the correct one!!)

So I added my example and thought I’d better run it through a current PHP-Version to check wether my code is actually sane and runs.

As the ICU-extension is not by default part of the images on docker-hub I created this little Dockerfile to get an image with the ICU extension:

FROM php:8.3-rc-fpm
MAINTAINER andreas@stella-maris.solutions

RUN apt-get update \
 && apt-get install -y libicu-dev \
 && docker-php-ext-configure intl --enable-intl \
 && docker-php-ext-install -j$(nproc) intl \

It’s using the latest PHP 8.3 image and adds the ICU extension. Yes! it’s not slim, there is cleanup missing etc but that is not the point here, it’s just to demonstrate something.

I created a container via docker build -t icutest .

So now let’s check the ICU version.

$ docker run icutest bash -c "php -i | grep -i icu"
ICU version => 72.1
ICU Data version => 72.1
ICU TZData version => 2022e
ICU Unicode version => 15.0
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Wait! ICU TZData version => 2022e?

As https://data.iana.org/time-zones/tzdb-2022e/ shows, that’s from October 2022! What the heck?

What’s the timezone-DB version that PHPs DateTime lib uses?

$ docker run icutest bash -c "php -i | grep -i Olson"
"Olson" Timezone Database Version => 2024.1

Oh! Great!

So we learn different things here:

PHP libraries use separate timezone-data

The DateTime extension (you know: date, DateTimeImmutable etc) use the latest timezone-db version available at compile time of the PHP-library. (Thank you Derick for that!) One of the reasons why one should stay up-to-date with PHP-versions. If that’s not possible, you can use the timezonedb pecl-package.

But the Intl Extension – as it is a wrapper around the ICU4C library – uses it’s own timezone database. Also the last one available at release time of the library.

So why do we have a mismatch there? Because at the time of writing the current release of ICU is 75.1 – and not 72.1 as the output of PHP-info shows.

The issue I am running into here is that I installed the libicu-dev package when building the container. And that installs the – by now outdated – ICU data as debian/ubuntu do not update those packages to higher major versions. An upgrade to a higher major version of a lib only happens when updating Debian/Ubuntu to a higher Major.

Despite the fact that neither Debian/Ubuntu nor ICU are using Semantic Versioning…

Don’t come with a problem!

OK. I now had analyzed the problem (my main problem was that the code didn’t run because I was using the bullseye image and not the bookworm one which is on an even older timezone DB that didn’t know Europe/Kyiv as it was from 2019…).

How to fix it?

Well, the solution seems simple: Update the ICU extension…

So I fiddled a bit around and updated another library to handle the non-semver versioning that ICU uses and ended up with this somewhat more complex Dockerfile

What happens here

Let’s shortly go through the dockerfile

In line 5 I install stuff that is necessary for compiling code as I will need to do that with the ICU lib.

In line 6 I download the latest version of the ICU4C library. It uses getlatestassets that will make sure that we will always get the latest relerased version. Sadly the github API doesn’t provide a way to do that out of the box, so I have to use getlatestassets.com here. To make handling easier I store the archive in a file consitently named icu.tgz

The next steps are to extract the archive and change the working directory.

In line 9 I set the LIBDIR variable from what is set for PHP so that the ICU library will afterwards be placed in the right folder where PHP expects all the libs to be. Otherwise I get some odd runtime errors when PHP tries to load a library that is not available.

In line 10 I tell the config script where to put that library file and then it’s make and make install to build and install the library.

Afterwards I remove the archive file. In a production image I’d do some more cleanup here to get the imagesize down.

After that it’s the same commands that I already used in the old Dockerfile, just this time the “correct” library-version will be used.

So let’s create and check the container:

Great! Now we have a current version of ICU with a rather recent version of the timezone-database. And also all the other awesome things that are part of a new ICU version! Like new translations, new emojis etc.

What did I learn?

Whenever I am using the Intl extension in PHP I will now make sure that the PHP-Version I am using is actually using the latest available ICU-library as one can not take for granted that that is delivered by default.

In essence I should probably check that for every library I use, but most of them do not contain such volatile information as the (constantly changing) timezone DB. And usually fixes for critical issues are ported to the respective libraries by the distros. But that requires me to keep on a distro-version that gets these patches!

So in essence the main thing is – as always – Stay up to date

Outlook.com and self-hosted email-servers

I am running my own email-server for some time now. It started out of curiosity and went live after my hosting-provider got hacked several times and I then was sick of it. It’s not as hard as people make one believe when it’s just for a few email-addresses. Still I check the server every now and then.

The setup and what I do in between might be a separate blogpost (or actually several) but today I just want to write about one thing that nagged me really deeply and where the solution was pretty easy. I had to think about it when Rob Allen today wrote about DKIM, SPF and DMARK.

What happened

Whenever I wanted to send an email to an outlook.com (or outlook.de or hotmail.com) address, that email just didn’t get through. It was considered spam and I received a nice feedback in the mailserver-log:

Continue reading Outlook.com and self-hosted email-servers →