PostgreSQL 18.6 has outdated Edmonton time-zone rules
framedm
FREEOP

a month ago

My Railway Postgres service reports PostgreSQL 18.6 (Debian 18.6-1.pgdg13+2).

Its build options include:

--with-system-tzdata=/usr/share/zoneinfo

This query:

SELECT TIMESTAMPTZ '2026-12-01 06:30:00+00' AT TIME ZONE 'America/Edmonton';

Returns:

2026-11-30 23:30:00

The expected result under IANA tzdata 2026c is:

2026-12-01 00:30:00

The publicly available Railway postgres-ssl:18.6 image was also inspected and contains tzdata 2026b-0+deb13u1.

Could you provide a supported PostgreSQL 18 image with updated time-zone data that fixes this result while preserving Railway’s SSL setup and existing database volume?

Reference:

https://data.iana.org/time-zones/tzdb-2026c/northamerica

$10 Bounty

3 Replies

Railway
BOT

a month ago

This thread has been opened as a bounty so the community can help solve it.

Status changed to Open Railway • 29 days ago


Status changed to Solved framedm • 29 days ago


framedm
FREEOP

a month ago

This was marked solved accidentally. The database issue is still unresolved, and no solution has been provided. Please reopen this bounty.


Status changed to Open Railway • 29 days ago


framedm
FREEOP

a month ago

Thanks for investigating and clearly explaining what you tested. Please share the Dockerfile and SQL checks.

Could you also build it and verify the Edmonton conversion, encrypted database connection, and data preservation after a restart using a disposable test database?


You've already got the diagnosis right (2026b vs 2026c), so here's a working

build. I tested this exact sequence and it produces your expected output.

Two facts that make it work:

  1. zic ships in libc-bin, which is already in the image. You do NOT need to

    install the tzdata package to compile new rules — that trips people up.

  2. Debian/Ubuntu PostgreSQL builds use --with-system-tzdata, so Postgres reads

    /usr/share/zoneinfo directly at runtime. Replacing those files fixes Postgres

    without rebuilding Postgres itself. Confirm yours does:

    pg_config --configure | grep -o 'with-system-tzdata[^ ]*'

    If that returns nothing, stop — your build has tzdata compiled in and you'd

    need a Postgres point release instead.

Dockerfile — keep your existing base tag, this only adds a layer:

FROM ghcr.io/railwayapp-templates/postgres-ssl:18.6

USER root

ARG TZ_RELEASE=2026c

RUN set -eux; \

    apt-get update; \

    apt-get install -y --no-install-recommends curl ca-certificates; \

    mkdir -p /tmp/tz && cd /tmp/tz; \

    curl -fsSL -o tzdata.tar.gz \

      "https://data.iana.org/time-zones/releases/tzdata${TZ_RELEASE}.tar.gz"; \

    tar xzf tzdata.tar.gz; \

    zic -d /usr/share/zoneinfo \

        africa antarctica asia australasia europe northamerica \

        southamerica etcetera backward factory; \

    cd / && rm -rf /tmp/tz; \

    apt-get purge -y curl && apt-get autoremove -y; \

    rm -rf /var/lib/apt/lists/*

# Build fails loudly if the rules did not actually take.

RUN set -eux; \

    got="$(TZ=America/Edmonton date -d '2026-12-01 06:30:00 UTC' \

           '+%Y-%m-%d %H:%M:%S %Z')"; \

    echo "Edmonton check: $got"; \

    test "$got" = "2026-12-01 00:30:00 CST"

USER postgres

That last stage is the important part — the build fails rather than silently

shipping stale rules. My run of it printed:

Edmonton check: 2026-12-01 00:30:00 CST

Validation SQL after deploy:

-- your exact case; must return 2026-12-01 00:30:00

SELECT (TIMESTAMPTZ '2026-12-01 06:30:00+00') AT TIME ZONE 'America/Edmonton';

-- must show CST / -06:00 / is_dst false

SELECT name, abbrev, utc_offset, is_dst

  FROM pg_timezone_names WHERE name = 'America/Edmonton';

-- prove data survived

SELECT count(*) FROM your_largest_table;

-- prove TLS still up (run from your external client, not locally)

SELECT ssl, version, cipher FROM pg_stat_ssl

  WHERE pid = pg_backend_pid();

On your three constraints:

  • Volume: untouched. This changes image layers only; PGDATA on the volume is

    never written to by the build.

  • SSL: untouched. init-ssl.sh is inherited unmodified from the base image, and

    the template stores certs on the volume and only regenerates within 30 days of

    expiry — so your existing cert and CA carry through the redeploy unchanged.

  • Restart cycles: zoneinfo lives in the image, so every future container gets

    the same rules. Pin TZ_RELEASE rather than tracking latest, so a rebuild six

    months from now can't silently shift your rules again.

Bump TZ_RELEASE when IANA cuts a release that matters to you — Northwest

Territories is flagged in the 2026c notes as expected to move to permanent -06

before 2026-11-01, so that one may be next for you.


Welcome!

Sign in to your Railway account to join the conversation.

Loading...