Catching Up: Upgrading Authentik from 2025.4 to 2026.6

Authentik

I had let authentik sit at 2025.4 for longer than I’d like to admit. Nothing was broken, so I kept deferring it. Eventually the version gap got uncomfortable enough that I blocked out an afternoon to sort it out.

Stepping through releases

Authentik’s upgrade docs are clear on one point: don’t skip versions. The official upgrade guide recommends going through each release in order. With eight releases between 2025.4 and 2026.6, that meant a few rounds of:

# docker-compose.yml — bump the image tag
image: ghcr.io/goauthentik/server:2025.6.x
image: ghcr.io/goauthentik/worker:2025.6.x

Then pull and restart:

docker compose pull
docker compose up -d

Wait for the migrations to finish, check the UI loads, then move to the next one. The full path I went through:

  • 2025.4 → 2025.6
  • 2025.6 → 2025.8
  • 2025.8 → 2025.10
  • 2025.10 → 2025.12
  • 2025.12 → 2026.2
  • 2026.2 → 2026.4
  • 2026.4 → 2026.6

Nothing blew up at any step. A few migrations ran that took a moment, and one release had a startup warning I checked the changelog for — it was just a deprecated config key I’d been carrying from an old compose file. Removed it, no issue.

Dropping Redis

Somewhere in this run of releases, authentik dropped the Redis requirement for the worker queue and moved to using PostgreSQL instead. That’s a meaningful simplification. One less container to maintain, one less thing to back up, one less reason for the stack to be unhappy at 3am.

The change was straightforward: remove the Redis service and its depends_on references from docker-compose.yml, and drop the AUTHENTIK_REDIS__HOST env var. After that authentik started up fine using Postgres for the task queue without any extra configuration.

Before:

services:
  redis:
    image: redis:alpine
    restart: unless-stopped

  server:
    environment:
      AUTHENTIK_REDIS__HOST: redis
    depends_on:
      - redis
      - postgresql

  worker:
    environment:
      AUTHENTIK_REDIS__HOST: redis
    depends_on:
      - redis
      - postgresql

After: just remove all of that. No Redis block, no AUTHENTIK_REDIS__HOST, no depends_on entry for it.

Upgrading Postgres to version 18

Once authentik was current, I took the opportunity to bump Postgres from 16 to 18. The official Docker upgrade guide covers this and it’s worth reading before doing anything.

The process uses pg_upgrade via the pgautoupgrade image, which handles the in-place migration. The short version:

  1. Stop authentik server and worker (leave Postgres running)
  2. Back up the data volume
  3. Swap the image to pgautoupgrade/pgautoupgrade:latest with PGAUTO_ONESHOT=yes set, pointing at the same data volume
  4. Let it run — it detects the old version, runs pg_upgrade, then exits
  5. Swap back to the standard postgres:18-alpine image
  6. Start everything back up
postgresql:
  image: pgautoupgrade/pgautoupgrade:latest
  environment:
    POSTGRES_PASSWORD: ${PG_PASS}
    POSTGRES_USER: authentik
    POSTGRES_DB: authentik
    PGAUTO_ONESHOT: "yes"
  volumes:
    - database:/var/lib/postgresql/data

Run it, watch the logs, confirm it exits cleanly, then switch the image back to postgres:18-alpine and bring the full stack up. Authentik came back without complaint.

Takeaways

The upgrade process for authentik is pretty solid when you follow it. Stepping through releases one at a time felt tedious but only took about an hour including wait time, and skipping steps seems like a genuine way to end up with a broken schema. The Redis removal was a nice quality-of-life change for a simple homelab setup, and Postgres 18 went in without incident.

Now I just need to actually do these more often than once a year.

← Back to all posts