Skip to content

Fix Zitadel Docker post for v4 Login V2 architecture (#148)#152

Merged
simlarsen merged 1 commit into
masterfrom
fix/zitadel-login-v2-issue-148
Jun 25, 2026
Merged

Fix Zitadel Docker post for v4 Login V2 architecture (#148)#152
simlarsen merged 1 commit into
masterfrom
fix/zitadel-login-v2-issue-148

Conversation

@simlarsen

Copy link
Copy Markdown
Contributor

What

Resolves #148. A reader asked where the zitadel-login service is and how login works without it. They were right to ask: the post deployed a single zitadel container with no login service, which no longer produces a working sign-in on current Zitadel.

Why it was broken

  • ghcr.io/zitadel/zitadel:latest now tracks the Zitadel v4 line (v4.15.3 at time of writing).
  • Zitadel v4 split the login UI out of the core into a standalone Next.js app shipped as its own image, ghcr.io/zitadel/zitadel-login ("Login V2"), served at /ui/v2/login on port 3000.
  • New v4 instances default to LoginV2 Required=true, so the core redirects sign-in to /ui/v2/login. With no login service running, the interactive login breaks (the API and console assets still work).
  • Login V1 is still bundled in v4 and can be re-enabled with ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_REQUIRED=false; it is not removed/deprecated yet.

Changes

  • Pin images to v4.15.3 instead of :latest in both examples.
  • Quick start sets ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_REQUIRED=false so the single-container evaluation setup keeps a working login (bundled Login V1 at /ui/login).
  • New section "Where Is the Login Service? Zitadel v4 and Login V2" explaining the architecture change.
  • Rewrote the production compose to the correct v4 layout: PostgreSQL + Zitadel core + the separate zitadel-login container + a Traefik reverse proxy, with the login-client PAT bootstrap and shared volume. Modeled on Zitadel's official deploy/compose/docker-compose.yml.
  • Updated the TLS section for proxy-terminated TLS; kept a direct-on-core option.
  • Standardized the Postgres image to postgres:17-alpine (production compose previously used 16).

npm run validate passes.

The post deployed a single zitadel container with no login service.
Since Zitadel v4 (which :latest now tracks), the login UI is a separate
Next.js container (ghcr.io/zitadel/zitadel-login, "Login V2"), and new
instances default to redirecting sign-in to it - so the documented login
flow breaks on current versions.

- Pin images to v4.15.3 instead of :latest in both examples
- Quick start sets LOGINV2_REQUIRED=false to keep the bundled legacy
  login working for single-container evaluation
- Add a section explaining the v2/v3 vs v4 login architecture
- Rewrite the production compose to the correct v4 layout: core +
  zitadel-login + Traefik proxy, with the login-client PAT bootstrap
  (modeled on Zitadel's official deploy/compose)
- Update TLS section for proxy-terminated TLS; keep direct-on-core option
- Standardize Postgres image to postgres:17-alpine
@simlarsen simlarsen merged commit 2f88968 into master Jun 25, 2026
2 checks passed
@simlarsen simlarsen deleted the fix/zitadel-login-v2-issue-148 branch June 25, 2026 19:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2026-02-08-how-to-run-zitadel-in-docker-for-iam - where is the zitadel-login service

2 participants