From cb9e8973ff1537b1f71d09765c418dcb832064e1 Mon Sep 17 00:00:00 2001 From: "CanbiZ (MickLesk)" <47820557+MickLesk@users.noreply.github.com> Date: Tue, 20 Oct 2026 13:16:44 +0200 Subject: [PATCH] Zitadel: Support v1 and v2 Login (#18031) * Zitadel: Support v1 and v2 Login * Refactor Zitadel installation and configuration process Refactor Zitadel installation script to improve configuration and setup processes, including PostgreSQL and Zitadel Login setup. * Update authorship information in zitadel-install.sh * Add co-authors to the zitadel.sh file Updated author information to include co-authors. * Enhance Zitadel login options descriptions * Change Zitadel login version check condition * Change session cookie secret generation method --- ct/zitadel.sh | 46 ++++++-- install/zitadel-install.sh | 219 ++++++++++++++++++++++--------------- 2 files changed, 167 insertions(+), 98 deletions(-) diff --git a/ct/zitadel.sh b/ct/zitadel.sh index b3277b691..d8b281093 100644 --- a/ct/zitadel.sh +++ b/ct/zitadel.sh @@ -2,7 +2,7 @@ _cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func" source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func") # Copyright (c) 2021-2026 community-scripts ORG -# Author: dave-yap (dave-yap) +# Author: dave-yap (dave-yap) | Co-Author: remz1337, MickLesk (CanbiZ) # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://zitadel.com/ | Github: https://github.com/zitadel/zitadel @@ -16,11 +16,23 @@ var_version="${var_version:-13}" var_arm64="${var_arm64:-yes}" var_unprivileged="${var_unprivileged:-1}" +if [[ -z "${var_zitadel_login:-}" ]] && command -v pveversion >/dev/null 2>&1; then + var_zitadel_login=$(msg_menu "Choose the Zitadel login UI" \ + "v2" "Login V2, Zitadel's default (HTTPS, self-signed certificate)" \ + "v1" "Login V1, the classic login built into the API (HTTP)") +fi +export var_zitadel_login="${var_zitadel_login:-v2}" + header_info "$APP" variables color catch_errors +if [[ ! "${var_zitadel_login}" =~ ^v[12]$ ]]; then + msg_error "var_zitadel_login must be v1 or v2" + exit 1 +fi + function update_script() { header_info check_container_storage @@ -31,20 +43,29 @@ function update_script() { fi if check_for_gh_release "zitadel" "zitadel/zitadel"; then - msg_info "Stopping Service" + msg_info "Stopping Zitadel" + if [[ -f /etc/systemd/system/zitadel-login.service ]]; then + systemctl stop zitadel-login + fi systemctl stop zitadel - msg_ok "Stopped Service" + msg_ok "Stopped Zitadel" - rm -f /usr/local/bin/zitadel - fetch_and_deploy_gh_release "zitadel" "zitadel/zitadel" "prebuild" "latest" "/usr/local/bin" "zitadel-linux-$(arch_resolve).tar.gz" + fetch_and_deploy_gh_release "zitadel" "zitadel/zitadel" "prebuild" "${CHECK_UPDATE_RELEASE}" "/usr/local/bin" "zitadel-linux-$(arch_resolve).tar.gz" + if [[ -f /etc/systemd/system/zitadel-login.service ]]; then + NODE_VERSION="24" setup_nodejs + CLEAN_INSTALL=1 fetch_and_deploy_gh_release "zitadel-login" "zitadel/zitadel" "prebuild" "${CHECK_UPDATE_RELEASE}" "/opt/zitadel-login" "zitadel-login.tar.gz" + fi - msg_info "Updating Zitadel" + msg_info "Migrating Zitadel Database" $STD zitadel setup --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml --init-projections=true - msg_ok "Updated Zitadel" + msg_ok "Migrated Zitadel Database" - msg_info "Starting Service" + msg_info "Starting Zitadel" systemctl start zitadel - msg_ok "Started Service" + if [[ -f /etc/systemd/system/zitadel-login.service ]]; then + systemctl start zitadel-login + fi + msg_ok "Started Zitadel" msg_ok "Updated successfully!" fi exit @@ -57,4 +78,9 @@ description msg_ok "Completed successfully!\n" echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}" echo -e "${INFO}${YW}Access it using the following URL:${CL}" -echo -e "${GATEWAY}${BGN}http://${IP}:8080/ui/console${CL}" +if [[ "${var_zitadel_login}" == "v1" ]]; then + echo -e "${GATEWAY}${BGN}http://${IP}:8080/ui/console${CL}" +else + echo -e "${GATEWAY}${BGN}https://${IP}:8080/ui/console${CL}" +fi +echo -e "${INFO}${YW}Admin credentials: ~/zitadel.creds (inside the container)${CL}" diff --git a/install/zitadel-install.sh b/install/zitadel-install.sh index 1888cbfe1..a3b3356b5 100644 --- a/install/zitadel-install.sh +++ b/install/zitadel-install.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Copyright (c) 2021-2026 community-scripts ORG -# Author: dave-yap +# Author: dave-yap (dave-yap) | Co-Author: remz1337, MickLesk (CanbiZ) # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://zitadel.com/ | Github: https://github.com/zitadel/zitadel @@ -13,131 +13,174 @@ setting_up_container network_check update_os -msg_info "Installing Dependencies (Patience)" -$STD apt install -y ca-certificates -msg_ok "Installed Dependecies" +var_zitadel_login="${var_zitadel_login:-v2}" PG_VERSION="17" setup_postgresql - -msg_info "Installing Postgresql" -DB_NAME="zitadel" -DB_USER="zitadel" -DB_PASS=$(random_password 13) -DB_ADMIN_USER="root" -DB_ADMIN_PASS=$(random_password 13) -systemctl start postgresql -$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';" -$STD sudo -u postgres psql -c "CREATE USER $DB_ADMIN_USER WITH PASSWORD '$DB_ADMIN_PASS' SUPERUSER;" -$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME OWNER $DB_ADMIN_USER;" -cat <~/zitadel.creds -Application Credentials -DB_NAME: $DB_NAME -DB_USER: $DB_USER -DB_PASS: $DB_PASS -DB_ADMIN_USER: $DB_ADMIN_USER -DB_ADMIN_PASS: $DB_ADMIN_PASS -EOF -msg_ok "Installed PostgreSQL" - +PG_DB_NAME="zitadel" PG_DB_USER="zitadel" setup_postgresql_db fetch_and_deploy_gh_release "zitadel" "zitadel/zitadel" "prebuild" "latest" "/usr/local/bin" "zitadel-linux-$(arch_resolve).tar.gz" -msg_info "Setting up Zitadel Environments" +msg_info "Configuring Zitadel" mkdir -p /opt/zitadel -echo "/opt/zitadel/config.yaml" >"/opt/zitadel/.config" -random_password 32 >"/opt/zitadel/.masterkey" -cat <~/zitadel.creds -Config location: $(cat "/opt/zitadel/.config") -Masterkey: $(cat "/opt/zitadel/.masterkey") -EOF +random_password 32 >/opt/zitadel/.masterkey +ADMIN_PASS="$(random_password 20)Aa1!" cat </opt/zitadel/config.yaml -Port: 8080 +ExternalDomain: ${LOCAL_IP} ExternalPort: 8080 -ExternalDomain: localhost -ExternalSecure: false TLS: Enabled: false - KeyPath: "" - Key: "" - CertPath: "" - Cert: "" - Database: postgres: Host: localhost Port: 5432 - Database: ${DB_NAME} + Database: zitadel User: - Username: ${DB_USER} - Password: ${DB_PASS} + Username: zitadel + Password: ${PG_DB_PASS} SSL: Mode: disable - RootCert: "" - Cert: "" - Key: "" - Admin: - Username: ${DB_ADMIN_USER} - Password: ${DB_ADMIN_PASS} - SSL: - Mode: disable - RootCert: "" - Cert: "" - Key: "" +EOF +if [[ "$var_zitadel_login" == "v1" ]]; then + cat <>/opt/zitadel/config.yaml +Port: 8080 +ExternalSecure: false DefaultInstance: Features: LoginV2: Required: false +FirstInstance: + Org: + Human: + UserName: zitadel-admin@zitadel.localhost + Password: ${ADMIN_PASS} + PasswordChangeRequired: true EOF -msg_ok "Installed Zitadel Enviroments" +else + cat <>/opt/zitadel/config.yaml +Port: 8081 +ExternalSecure: true +DefaultInstance: + Features: + LoginV2: + Required: true +FirstInstance: + LoginClientPatPath: /opt/zitadel/login-client.pat + Org: + Human: + UserName: zitadel-admin@zitadel.localhost + Password: ${ADMIN_PASS} + PasswordChangeRequired: true + LoginClient: + Machine: + Username: login-client + Name: Automatically Initialized IAM_LOGIN_CLIENT + Pat: + ExpirationDate: 2099-01-01T00:00:00Z +EOF +fi +chmod 600 /opt/zitadel/.masterkey /opt/zitadel/config.yaml +msg_ok "Configured Zitadel" -msg_info "Creating Services" +msg_info "Initializing Zitadel" +$STD zitadel init zitadel --config /opt/zitadel/config.yaml +$STD zitadel setup --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml --steps /opt/zitadel/config.yaml +cat <>~/zitadel.creds + +Zitadel Admin +Username: zitadel-admin@zitadel.localhost +Initial Password: ${ADMIN_PASS} +EOF +chmod 600 ~/zitadel.creds +msg_ok "Initialized Zitadel" + +msg_info "Creating Service" cat </etc/systemd/system/zitadel.service [Unit] -Description=ZITADEL Identiy Server +Description=Zitadel After=network.target postgresql.service Wants=postgresql.service [Service] Type=simple -User=zitadel -Group=zitadel -ExecStart=/usr/local/bin/zitadel start --masterkeyFile "/opt/zitadel/.masterkey" --config "/opt/zitadel/config.yaml" +ExecStart=/usr/local/bin/zitadel start --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml Restart=always RestartSec=5 -TimeoutStartSec=0 - -# Security Hardening options -ProtectSystem=full -ProtectHome=true -PrivateTmp=true -NoNewPrivileges=true [Install] WantedBy=multi-user.target EOF -systemctl enable -q zitadel -msg_ok "Created Services" +systemctl enable -q --now zitadel +msg_ok "Created Service" -msg_info "Zitadel initial setup" -$STD zitadel init --config /opt/zitadel/config.yaml -$STD zitadel setup --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml -useradd zitadel -msg_ok "Zitadel initialized" +if [[ "$var_zitadel_login" != "v1" ]]; then + NODE_VERSION="24" setup_nodejs + fetch_and_deploy_gh_release "zitadel-login" "zitadel/zitadel" "prebuild" "latest" "/opt/zitadel-login" "zitadel-login.tar.gz" -msg_info "Set ExternalDomain to current IP and restart Zitadel" -IP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) -sed -i "0,/localhost/s/localhost/${IP}/" /opt/zitadel/config.yaml -systemctl stop -q zitadel -$STD zitadel setup --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml -systemctl restart -q zitadel -msg_ok "Zitadel restarted with ExternalDomain set to current IP" - -msg_info "Create zitadel-rerun.sh" -cat <~/zitadel-rerun.sh -systemctl stop zitadel -timeout --kill-after=5s 15s zitadel setup --masterkeyFile /opt/zitadel/.masterkey --config /opt/zitadel/config.yaml -systemctl restart zitadel + msg_info "Setting up Zitadel Login" + $STD apt install -y nginx + create_self_signed_cert "zitadel" + cat </opt/zitadel/login.env +ZITADEL_API_URL=http://127.0.0.1:8081 +ZITADEL_API_AWAITINITIALCONN=5m +ZITADEL_SERVICE_USER_TOKEN_FILE=/opt/zitadel/login-client.pat +ZITADEL_SESSION_COOKIE_SECRET=$(random_password 48) +NEXT_PUBLIC_BASE_PATH=/ui/v2/login +HOSTNAME=127.0.0.1 +PORT=3000 EOF -msg_ok "Bash script for rerunning Zitadel after changing Zitadel config.yaml" + chmod 600 /opt/zitadel/login.env /opt/zitadel/login-client.pat + cat </etc/systemd/system/zitadel-login.service +[Unit] +Description=Zitadel Login +After=network.target zitadel.service +Wants=zitadel.service + +[Service] +Type=simple +WorkingDirectory=/opt/zitadel-login +EnvironmentFile=/opt/zitadel/login.env +ExecStart=/opt/zitadel-login/entrypoint.sh node apps/login/server.js +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + systemctl enable -q --now zitadel-login + cat <<'EOF' >/etc/nginx/sites-available/zitadel +server { + listen 8080 ssl; + http2 on; + server_name _; + ssl_certificate /etc/ssl/zitadel/zitadel.crt; + ssl_certificate_key /etc/ssl/zitadel/zitadel.key; + error_page 497 =301 https://$http_host$request_uri; + + location = / { + return 302 /ui/v2/login/; + } + + location /ui/v2/login { + proxy_pass http://127.0.0.1:3000; + proxy_http_version 1.1; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /api/ { + rewrite ^/api(/.*)$ $1 break; + grpc_pass grpc://127.0.0.1:8081; + grpc_set_header Host $http_host; + } + + location / { + grpc_pass grpc://127.0.0.1:8081; + grpc_set_header Host $http_host; + } +} +EOF + nginx_enable_site "zitadel" + msg_ok "Set up Zitadel Login" +fi motd_ssh customize