From a6ccb34eff0779e43b875eef7e24182764853c57 Mon Sep 17 00:00:00 2001
From: Stefan Benz <46600784+stebenz@users.noreply.github.com>
Date: Wed, 2 Jul 2025 10:47:51 +0200
Subject: [PATCH] docs: self-hosting with login v2
---
.../deploy/loadbalancing-example/.gitignore | 2 +-
.../loadbalancing-example/docker-compose.yaml | 69 ++++++-------------
.../example-zitadel-config.yaml | 7 +-
.../example-zitadel-init-steps.yaml | 11 +--
.../loadbalancing-example.mdx | 8 ++-
docs/docs/self-hosting/deploy/macos.mdx | 25 +++++--
6 files changed, 56 insertions(+), 66 deletions(-)
diff --git a/docs/docs/self-hosting/deploy/loadbalancing-example/.gitignore b/docs/docs/self-hosting/deploy/loadbalancing-example/.gitignore
index bd98bacd66..0f46fa7086 100644
--- a/docs/docs/self-hosting/deploy/loadbalancing-example/.gitignore
+++ b/docs/docs/self-hosting/deploy/loadbalancing-example/.gitignore
@@ -1 +1 @@
-.env-file
+pat
\ No newline at end of file
diff --git a/docs/docs/self-hosting/deploy/loadbalancing-example/docker-compose.yaml b/docs/docs/self-hosting/deploy/loadbalancing-example/docker-compose.yaml
index 013fc2aa22..e3f92d2a8b 100644
--- a/docs/docs/self-hosting/deploy/loadbalancing-example/docker-compose.yaml
+++ b/docs/docs/self-hosting/deploy/loadbalancing-example/docker-compose.yaml
@@ -22,7 +22,10 @@ services:
networks:
- 'storage'
image: 'ghcr.io/zitadel/zitadel:latest'
- command: 'init --config /example-zitadel-config.yaml --config /example-zitadel-secrets.yaml'
+ command: >
+ init
+ --config /example-zitadel-config.yaml
+ --config /example-zitadel-secrets.yaml
depends_on:
db:
condition: 'service_healthy'
@@ -34,32 +37,18 @@ services:
restart: 'no'
networks:
- 'storage'
- # We use the debug image so we have the environment to
- # - create the .env file for the login to authenticate at Zitadel
- # - set the correct permissions for the .env-file folder
- image: 'ghcr.io/zitadel/zitadel:latest-debug'
- user: root
- entrypoint: '/bin/sh'
- command:
- - -c
- - >
- /app/zitadel setup
+ image: 'ghcr.io/zitadel/zitadel:latest'
+ command: >
+ setup
--config /example-zitadel-config.yaml
--config /example-zitadel-secrets.yaml
--steps /example-zitadel-init-steps.yaml
- --masterkey ${ZITADEL_MASTERKEY} &&
- mv /pat /.env-file/pat || exit 0 &&
- echo ZITADEL_SERVICE_USER_TOKEN=$(cat /.env-file/pat) > /.env-file/.env &&
- chown -R 1001:${GID} /.env-file &&
- chmod -R 770 /.env-file
- environment:
- - GID
+ --masterkey ${ZITADEL_MASTERKEY}
depends_on:
zitadel-init:
condition: 'service_completed_successfully'
- restart: false
volumes:
- - './.env-file:/.env-file:rw'
+ - '.:/pat-dir:rw'
- './example-zitadel-config.yaml:/example-zitadel-config.yaml:ro'
- './example-zitadel-secrets.yaml:/example-zitadel-secrets.yaml:ro'
- './example-zitadel-init-steps.yaml:/example-zitadel-init-steps.yaml:ro'
@@ -71,7 +60,8 @@ services:
- 'storage'
image: 'ghcr.io/zitadel/zitadel:latest'
command: >
- start --config /example-zitadel-config.yaml
+ start
+ --config /example-zitadel-config.yaml
--config /example-zitadel-secrets.yaml
--masterkey ${ZITADEL_MASTERKEY}
depends_on:
@@ -94,40 +84,18 @@ services:
retries: 5
start_period: 10s
- # The use-new-login service configures Zitadel to use the new login v2 for all applications.
- # It also gives the setupped machine user the necessary IAM_LOGIN_CLIENT role.
- use-new-login:
- restart: 'on-failure'
- user: "1001"
- networks:
- - 'backend'
- image: 'badouralix/curl-jq:alpine'
- entrypoint: '/bin/sh'
- command:
- - -c
- - >
- curl -X PUT -H "Host: 127.0.0.1.sslip.io" -H "Authorization: Bearer $(cat ./.env-file/pat)" --insecure http://zitadel:8080/v2/features/instance -d '{"loginV2": {"required": true}}' &&
- LOGIN_USER=$(curl --fail-with-body -H "Host: 127.0.0.1.sslip.io" -H "Authorization: Bearer $(cat ./.env-file/pat)" --insecure http://zitadel:8080/auth/v1/users/me | jq -r '.user.id') &&
- curl -X PUT -H "Host: 127.0.0.1.sslip.io" -H "Authorization: Bearer $(cat ./.env-file/pat)" --insecure http://zitadel:8080/admin/v1/members/$${LOGIN_USER} -d '{"roles": ["IAM_OWNER", "IAM_LOGIN_CLIENT"]}'
- volumes:
- - './.env-file:/.env-file:ro'
- depends_on:
- zitadel:
- condition: 'service_healthy'
- restart: false
-
login:
restart: 'unless-stopped'
networks:
- 'backend'
- image: 'ghcr.io/zitadel/login:main'
+ image: 'ghcr.io/zitadel/login:latest'
environment:
- ZITADEL_API_URL=http://zitadel:8080
- CUSTOM_REQUEST_HEADERS=Host:127.0.0.1.sslip.io
- NEXT_PUBLIC_BASE_PATH="/ui/v2/login"
- user: "${UID:-1000}"
- volumes:
- - './.env-file:/.env-file:ro'
+ - ZITADEL_SERVICE_USER_TOKEN_FILE=/run/secrets/login-client-pat
+ secrets:
+ - login-client-pat
depends_on:
zitadel:
condition: 'service_healthy'
@@ -149,9 +117,14 @@ services:
login:
condition: 'service_started'
+secrets:
+ login-client-pat:
+ file: './login-client-pat'
+
+
networks:
storage:
backend:
volumes:
- data:
+ data:
\ No newline at end of file
diff --git a/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-config.yaml b/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-config.yaml
index fadd39373d..0979fd18ad 100644
--- a/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-config.yaml
+++ b/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-config.yaml
@@ -16,14 +16,9 @@ Database:
User.SSL.Mode: 'disable'
Admin.SSL.Mode: 'disable'
-# By default, ZITADEL should redirect to /ui/v2/login
-OIDC:
- DefaultLoginURLV2: "/ui/v2/login/login?authRequest=" # ZITADEL_OIDC_DEFAULTLOGINURLV2
- DefaultLogoutURLV2: "/ui/v2/login/logout?post_logout_redirect=" # ZITADEL_OIDC_DEFAULTLOGOUTURLV2
-SAML.DefaultLoginURLV2: "/ui/v2/login/login?authRequest=" # ZITADEL_SAML_DEFAULTLOGINURLV2
-
# Access logs allow us to debug Network issues
LogStore.Access.Stdout.Enabled: true
# Skipping the MFA init step allows us to immediately authenticate at the console
DefaultInstance.LoginPolicy.MfaInitSkipLifetime: "0s"
+DefaultInstance.PrivacyPolicy.TOSLink: example.com
\ No newline at end of file
diff --git a/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-init-steps.yaml b/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-init-steps.yaml
index be63164ced..b7a16c735b 100644
--- a/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-init-steps.yaml
+++ b/docs/docs/self-hosting/deploy/loadbalancing-example/example-zitadel-init-steps.yaml
@@ -1,12 +1,13 @@
# All possible options and their defaults: https://github.com/zitadel/zitadel/blob/main/cmd/setup/steps.yaml
FirstInstance:
- PatPath: '/pat'
+ PatPath: '/pat-dir/pat'
+ LoginClientPatPath: '/pat-dir/login-client-pat'
Org:
# We want to authenticate immediately at the console without changing the password
Human:
PasswordChangeRequired: false
- Machine:
+ LoginClient:
Machine:
- Username: 'login-container'
- Name: 'Login Container'
- Pat.ExpirationDate: '2029-01-01T00:00:00Z'
+ Username: 'login-client'
+ Name: 'Login Client'
+ Pat.ExpirationDate: '2029-01-01T00:00:00Z'
\ No newline at end of file
diff --git a/docs/docs/self-hosting/deploy/loadbalancing-example/loadbalancing-example.mdx b/docs/docs/self-hosting/deploy/loadbalancing-example/loadbalancing-example.mdx
index d4c27ccd95..0d3f6f9b48 100644
--- a/docs/docs/self-hosting/deploy/loadbalancing-example/loadbalancing-example.mdx
+++ b/docs/docs/self-hosting/deploy/loadbalancing-example/loadbalancing-example.mdx
@@ -60,9 +60,13 @@ wget https://raw.githubusercontent.com/zitadel/zitadel/main/docs/docs/self-hosti
# A single ZITADEL instance always needs the same 32 bytes long masterkey
# Generate one to a file if you haven't done so already and pass it as environment variable
-LC_ALL=C tr -dc '[:graph:]' ./zitadel-masterkey
+LC_ALL=C tr -dc '[:alpha:]' ./zitadel-masterkey
export ZITADEL_MASTERKEY="$(cat ./zitadel-masterkey)"
+# make sure the file ./pat exists so docker compose doesn't complain
+# it will be overwritten by the setup job
+echo "overwritten" > ./pat
+
# Run the database and application containers
docker compose up --detach --wait
```
@@ -71,4 +75,4 @@ Open your favorite internet browser at https://127.0.0.1.sslip.io/ui/console?log
Your browser warns you about the insecure self-signed TLS certificate. As 127.0.0.1.sslip.io resolves to your localhost, you can safely proceed.
Use the password *Password1!* to log in.
-Read more about [the login process](/guides/integrate/login/oidc/login-users).
+Read more about [the login process](/guides/integrate/login/oidc/login-users).
\ No newline at end of file
diff --git a/docs/docs/self-hosting/deploy/macos.mdx b/docs/docs/self-hosting/deploy/macos.mdx
index beb3182208..c078ace9db 100644
--- a/docs/docs/self-hosting/deploy/macos.mdx
+++ b/docs/docs/self-hosting/deploy/macos.mdx
@@ -26,13 +26,14 @@ sudo pg_ctl start -D /tmp/postgresql
```bash
brew install zitadel/tap/zitadel
+brew install node
```
### Download from GitHub
Download the ZITADEL release according to your architecture from [Github](https://github.com/zitadel/zitadel/releases/latest)
-## Unpack the archive
+#### Unpack the archive
move to your download location and unpack the archive
```bash
@@ -40,10 +41,26 @@ move to your download location and unpack the archive
LATEST=$(curl -i https://github.com/zitadel/zitadel/releases/latest | grep location: | cut -d '/' -f 8 | tr -d '\r'); wget -qO- https://github.com/zitadel/zitadel/releases/download/$LATEST/zitadel_Darwin_$(uname -m).tar.gz | tar -xJ zitadel && sudo mv zitadel /usr/local/bin
```
-## Run ZITADEL
+#### Run ZITADEL
```bash
-ZITADEL_DATABASE_POSTGRES_HOST=localhost ZITADEL_DATABASE_POSTGRES_PORT=5432 ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=zitadel ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=disable ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=$(whoami) ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD=postgres ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable ZITADEL_EXTERNALSECURE=false zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
+export ZITADEL_LOGIN_CLIENT_PAT_PATH=$(pwd)/login-client-pat
+ZITADEL_DATABASE_POSTGRES_HOST=localhost ZITADEL_DATABASE_POSTGRES_PORT=5432 ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=zitadel ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=disable ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=$(whoami) ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD=postgres ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable ZITADEL_EXTERNALSECURE=false ZITADEL_FIRSTINSTANCE_LOGINCLIENTPATPATH=$(echo $ZITADEL_LOGIN_CLIENT_PAT_PATH) ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_USERNAME=zitadel-login-client ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_NAME=zitadel-login-client ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_PAT_EXPIRATIONDATE=2099-01-01T00:00:00Z zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
+```
+
+#### Unpack the login archive
+
+```bash
+mkdir zitadel-login
+#unpack and copy to /usr/local/bin
+LATEST=$(curl -i https://github.com/zitadel/zitadel/releases/latest | grep location: | cut -d '/' -f 8 | tr -d '\r'); wget -qO- https://github.com/zitadel/zitadel/releases/download/$LATEST/login.tar.gz | tar -xzv -C zitadel-login
+
+```
+
+#### Run ZITADEL Login
+
+```bash
+ZITADEL_API_URL=http://localhost:8080 ZITADEL_SERVICE_USER_TOKEN=$(cat $ZITADEL_LOGIN_CLIENT_PAT_PATH) node apps/login/server.js
```
@@ -64,4 +81,4 @@ mv /tmp/zitadel-admin-sa.json $HOME/zitadel-admin-sa.json
This key can be used to provision resources with for example [Terraform](/docs/guides/manage/terraform-provider).
-
+
\ No newline at end of file