From 6786237720611c0342a8e5dd2773c2d762f4f5e2 Mon Sep 17 00:00:00 2001 From: Mauricio Siu Date: Tue, 14 Jul 2026 11:12:30 -0600 Subject: [PATCH] fix(zitadel): wire EXTERNALDOMAIN/PORT/SECURE to the generated domain Zitadel resolves its instance from the external domain/port/scheme, so the template's ZITADEL_EXTERNALPORT=8080 made every generated URL (OIDC issuer, login redirects) point at http://:8080 instead of the domain served by Traefik, ending in {"code":5,"message":"Not Found"} (#516). - Expose ZITADEL_EXTERNALDOMAIN / ZITADEL_EXTERNALPORT / ZITADEL_EXTERNALSECURE as template env vars, defaulting to the generated domain over HTTP (port 80, secure=false) so the routed domain and Zitadel's external config always match; HTTPS users flip them to 443/true in the Env tab. - Pin image to v4.16.0 (was latest) and keep the built-in login v1 via ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_REQUIRED=false so no separate login-v2 container is needed. - Add the official readiness healthcheck, drop the unused /app/data volume, bogus SMTP env keys, published port and obsolete compose version key. Closes #516 Co-Authored-By: Claude Fable 5 --- blueprints/zitadel/docker-compose.yml | 37 ++++++++++++++------------- blueprints/zitadel/meta.json | 2 +- blueprints/zitadel/template.toml | 14 +++++++--- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/blueprints/zitadel/docker-compose.yml b/blueprints/zitadel/docker-compose.yml index aaa457c3..ba7322e2 100644 --- a/blueprints/zitadel/docker-compose.yml +++ b/blueprints/zitadel/docker-compose.yml @@ -1,9 +1,7 @@ -version: '3.8' - services: zitadel: restart: 'always' - image: 'ghcr.io/zitadel/zitadel:latest' + image: 'ghcr.io/zitadel/zitadel:v4.16.0' command: 'start-from-init --masterkey "${ZITADEL_MASTERKEY}" --tlsMode disabled' environment: # Database Configuration @@ -17,33 +15,37 @@ services: ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: "${POSTGRES_PASSWORD}" ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE: disable - # External Configuration for HTTP only - TLS mode disabled - ZITADEL_EXTERNALSECURE: false - ZITADEL_EXTERNALPORT: 8080 - ZITADEL_EXTERNALDOMAIN: "${EXTERNAL_DOMAIN}" + # External access configuration. These MUST match the domain configured + # in the Domains tab and the scheme/port it is served on, otherwise + # Zitadel answers {"code":5,"message":"Not Found"}. + # HTTP -> ZITADEL_EXTERNALPORT=80, ZITADEL_EXTERNALSECURE=false + # HTTPS -> ZITADEL_EXTERNALPORT=443, ZITADEL_EXTERNALSECURE=true + ZITADEL_EXTERNALDOMAIN: "${ZITADEL_EXTERNALDOMAIN}" + ZITADEL_EXTERNALPORT: "${ZITADEL_EXTERNALPORT}" + ZITADEL_EXTERNALSECURE: "${ZITADEL_EXTERNALSECURE}" ZITADEL_TLS_ENABLED: false - # Disable Email Notifications - ZITADEL_NOTIFICATIONS_SMTP_HOST: "" - ZITADEL_NOTIFICATIONS_SMTP_PORT: "" - # Custom Admin User Configuration ZITADEL_FIRSTINSTANCE_ORG_HUMAN_USERNAME: "${ZITADEL_FIRSTINSTANCE_ORG_HUMAN_USERNAME}" ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD: "${ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD}" ZITADEL_FIRSTINSTANCE_ORG_HUMAN_EMAIL_ADDRESS: "${ZITADEL_FIRSTINSTANCE_ORG_HUMAN_EMAIL_ADDRESS}" ZITADEL_FIRSTINSTANCE_ORG_HUMAN_FIRSTNAME: "${ZITADEL_FIRSTINSTANCE_ORG_HUMAN_FIRSTNAME}" ZITADEL_FIRSTINSTANCE_ORG_HUMAN_LASTNAME: "${ZITADEL_FIRSTINSTANCE_ORG_HUMAN_LASTNAME}" - - # Default Instance Features + + # Use the login UI built into the API container (no extra login-v2 service needed) ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_REQUIRED: false + healthcheck: + test: ["CMD", "/app/zitadel", "ready"] + interval: '10s' + timeout: '30s' + retries: 12 + start_period: '30s' depends_on: db: condition: 'service_healthy' - ports: - - '8080' - volumes: - - zitadel_data:/app/data + expose: + - 8080 db: restart: 'always' @@ -63,4 +65,3 @@ services: volumes: postgres_data: - zitadel_data: \ No newline at end of file diff --git a/blueprints/zitadel/meta.json b/blueprints/zitadel/meta.json index 05917241..ac66c4b5 100644 --- a/blueprints/zitadel/meta.json +++ b/blueprints/zitadel/meta.json @@ -1,7 +1,7 @@ { "id": "zitadel", "name": "Zitadel", - "version": "latest", + "version": "4.16.0", "description": "Open-source identity and access management platform with multi-tenancy, OpenID Connect, SAML, and OAuth 2.0 support.", "logo": "zitadel.png", "links": { diff --git a/blueprints/zitadel/template.toml b/blueprints/zitadel/template.toml index f04da0be..44c177e5 100644 --- a/blueprints/zitadel/template.toml +++ b/blueprints/zitadel/template.toml @@ -7,6 +7,8 @@ admin_email = "${email}" admin_password = "AdminPassword123!" [config] +mounts = [] + [[config.domains]] serviceName = "zitadel" port = 8080 @@ -16,7 +18,15 @@ path = "/" [config.env] POSTGRES_PASSWORD = "${postgres_password}" ZITADEL_MASTERKEY = "${zitadel_masterkey}" -EXTERNAL_DOMAIN = "${main_domain}" + +# ZITADEL_EXTERNALDOMAIN must always match the domain configured in the +# Domains tab. If you change the domain, update this variable too (and do it +# BEFORE the first deploy — Zitadel binds its instance to this domain on +# first start). For a domain served over HTTPS set ZITADEL_EXTERNALPORT=443 +# and ZITADEL_EXTERNALSECURE=true. +ZITADEL_EXTERNALDOMAIN = "${main_domain}" +ZITADEL_EXTERNALPORT = "80" +ZITADEL_EXTERNALSECURE = "false" # Custom Admin User Configuration ZITADEL_FIRSTINSTANCE_ORG_HUMAN_USERNAME = "${admin_username}" @@ -24,5 +34,3 @@ ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD = "${admin_password}" ZITADEL_FIRSTINSTANCE_ORG_HUMAN_EMAIL_ADDRESS = "${admin_email}" ZITADEL_FIRSTINSTANCE_ORG_HUMAN_FIRSTNAME = "Admin" ZITADEL_FIRSTINSTANCE_ORG_HUMAN_LASTNAME = "User" - -[[config.mounts]]