Merge pull request #1427 from remz1337/pr-zitadel
Some checks failed
Update GitHub Versions (New) / update-github-versions (push) Has been cancelled
Crawl Versions from newreleases.io / crawl-versions (push) Has been cancelled
Crawl Versions from github / crawl-versions (push) Has been cancelled
Update Versions from GitHub / update-versions (push) Has been cancelled

Refactor Zitadel script to support Login V2
This commit is contained in:
CanbiZ (MickLesk) 2026-02-07 08:12:38 +01:00 committed by GitHub
commit ba23b7dcf9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 436 additions and 0 deletions

68
ct/zitadel.sh Normal file
View File

@ -0,0 +1,68 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: dave-yap (dave-yap) | Co-author: remz1337
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://zitadel.com/
APP="Zitadel"
var_tags="${var_tags:-identity-provider}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-6}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /etc/systemd/system/zitadel-api.service ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "zitadel" "zitadel/zitadel"; then
msg_info "Stopping Service"
systemctl stop zitadel-api zitadel-login
msg_ok "Stopped Service"
msg_info "Updating Zitadel"
rm -f /opt/zitadel/*
fetch_and_deploy_gh_release "zitadel" "zitadel/zitadel" "prebuild" "latest" "/opt/zitadel" "zitadel-linux-amd64.tar.gz"
rm -f /opt/login/*
fetch_and_deploy_gh_release "login" "zitadel/zitadel" "prebuild" "latest" "/opt/login" "zitadel-login.tar.gz"
cd /opt/zitadel
./zitadel setup --masterkeyFile /etc/zitadel/.masterkey --config /etc/zitadel/config.yaml --init-projections=true
msg_ok "Updated Zitadel"
msg_info "Starting Service"
systemctl start zitadel
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_info "Setting Container to Normal Resources"
pct set $CTID -memory 1024
pct set $CTID -cores 1
msg_ok "Set Container to Normal Resources"
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 "${TAB}${GATEWAY}${BGN}http://${IP}:8080/ui/console${CL}"
echo -e "${INFO} All credentials are saved in: /etc/zitadel/INSTALLATION_INFO.txt${CL}"

View File

@ -0,0 +1,44 @@
{
"name": "Zitadel",
"slug": "zitadel",
"categories": [
6
],
"date_created": "2025-02-10",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8080,
"documentation": "https://zitadel.com/docs/guides/overview",
"website": "https://zitadel.com",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/zitadel.webp",
"config_path": "/etc/zitadel/config.yaml",
"description": "Zitadel is an open-source identity and access management (IAM) solution designed to provide secure authentication, authorization, and user management for modern applications and services. Built with a focus on flexibility, scalability, and security, Zitadel offers a comprehensive set of features for developers and organizations looking to implement robust identity management.",
"install_methods": [
{
"type": "default",
"script": "ct/zitadel.sh",
"resources": {
"cpu": 1,
"ram": 1024,
"hdd": 6,
"os": "debian",
"version": "13"
}
}
],
"default_credentials": {
"username": "zitadel-admin@zitadel.localhost",
"password": "Password1!"
},
"notes": [
{
"text": "Application credentials: `cat /etc/zitadel/INSTALLATION_INFO.txt`",
"type": "info"
},
{
"text": "Change the ExternalDomain value in `/etc/zitadel/config.yaml` to your domain/hostname/IP and run `bash zitadel-rerun.sh`",
"type": "info"
}
]
}

324
install/zitadel-install.sh Normal file
View File

@ -0,0 +1,324 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: dave-yap (dave-yap) | Co-Author: remz1337
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://zitadel.com/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
# Configuration variables
ZITADEL_DIR="/opt/zitadel"
LOGIN_DIR="/opt/login"
CONFIG_DIR="/etc/zitadel"
ZITADEL_USER="zitadel"
ZITADEL_GROUP="zitadel"
DB_NAME="zitadel"
DB_USER="zitadel"
DB_PASSWORD="$(openssl rand -base64 32 | tr -d '=/+' | head -c 32)"
POSTGRES_ADMIN_PASSWORD="$(openssl rand -base64 32 | tr -d '=/+' | head -c 32)"
MASTERKEY="$(openssl rand -base64 32 | tr -d '=/+' | head -c 32)"
API_PORT="8080"
LOGIN_PORT="3000"
# Detect server IP address
SERVER_IP=$(hostname -I | awk '{print $1}')
msg_info "Installing Dependencies (Patience)"
$STD apt install -y ca-certificates
msg_ok "Installed Dependecies"
# Create zitadel user
msg_info "Creating zitadel system user"
groupadd --system "${ZITADEL_GROUP}"
useradd --system --gid "${ZITADEL_GROUP}" --shell /bin/bash --home-dir "${ZITADEL_DIR}" "${ZITADEL_USER}"
msg_ok "Created zitadel system user"
fetch_and_deploy_gh_release "zitadel" "zitadel/zitadel" "prebuild" "latest" "${ZITADEL_DIR}" "zitadel-linux-amd64.tar.gz"
chown -R "${ZITADEL_USER}:${ZITADEL_GROUP}" "${ZITADEL_DIR}"
fetch_and_deploy_gh_release "login" "zitadel/zitadel" "prebuild" "latest" "${LOGIN_DIR}" "zitadel-login.tar.gz"
chown -R "${ZITADEL_USER}:${ZITADEL_GROUP}" "${LOGIN_DIR}"
NODE_VERSION="24" setup_nodejs
PG_VERSION="17" setup_postgresql
setup_go
msg_info "Configuring Postgresql"
$STD sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '${POSTGRES_ADMIN_PASSWORD}';"
msg_ok "Configured PostgreSQL"
msg_info "Installing Zitadel"
cd "${ZITADEL_DIR}"
mkdir -p ${CONFIG_DIR}
echo "${MASTERKEY}" > ${CONFIG_DIR}/.masterkey
# Update config.yaml for network access
cat > "${CONFIG_DIR}/config.yaml" <<EOF
ExternalSecure: false
ExternalDomain: ${SERVER_IP}
ExternalPort: ${API_PORT}
TLS:
Enabled: false
Log:
Level: info
Formatter:
Format: text
Database:
Postgres:
Database: ${DB_NAME}
Host: localhost
Port: 5432
AwaitInitialConn: 5m
MaxOpenConns: 20
MaxIdleConns: 20
ConnMaxLifetime: 60m
ConnMaxIdleTime: 10m
User:
Username: ${DB_USER}
Password: ${DB_PASSWORD}
SSL:
Mode: disable
Admin:
Username: postgres
Password: ${POSTGRES_ADMIN_PASSWORD}
SSL:
Mode: disable
FirstInstance:
LoginClientPatPath: login-client.pat
PatPath: admin.pat
InstanceName: ZITADEL
DefaultLanguage: en
Org:
LoginClient:
Machine:
Username: login-client
Name: Automatically Initialized IAM Login Client
Pat:
ExpirationDate: 2099-01-01T00:00:00Z
Machine:
Machine:
Username: admin
Name: Automatically Initialized IAM admin Client
Pat:
ExpirationDate: 2099-01-01T00:00:00Z
Human:
Username: zitadel-admin@zitadel.localhost
Password: Password1!
PasswordChangeRequired: false
DefaultInstance:
Features:
LoginV2:
BaseURI: http://${SERVER_IP}:${LOGIN_PORT}/ui/v2/login
EOF
chown "${ZITADEL_USER}:${ZITADEL_GROUP}" "${CONFIG_DIR}/config.yaml"
# Initialize database as zitadel user (no masterkey needed for init)
$STD ./zitadel init --config ${CONFIG_DIR}/config.yaml
# Run setup phase as zitadel user (with masterkey and steps)
$STD ./zitadel setup --config ${CONFIG_DIR}/config.yaml --steps ${CONFIG_DIR}/config.yaml --masterkey "${MASTERKEY}"
#Read client token
CLIENT_PAT=$(cat ${ZITADEL_DIR}/login-client.pat)
# Update Login V2 login.env file
cat > "${CONFIG_DIR}/login.env" <<EOF
NEXT_PUBLIC_BASE_PATH=/ui/v2/login
EMAIL_VERIFICATION=false
ZITADEL_API_URL=http://${SERVER_IP}:${API_PORT}
ZITADEL_SERVICE_USER_TOKEN_FILE=../../login-client.pat
ZITADEL_SERVICE_USER_TOKEN=${CLIENT_PAT}
EOF
chown "${ZITADEL_USER}:${ZITADEL_GROUP}" "${CONFIG_DIR}/login.env"
# Update package.json to bind to 0.0.0.0 instead of 127.0.0.1
#sed -i 's/"prod": "cd \.\/\.next\/standalone && HOSTNAME=127\.0\.0\.1/"prod": "cd .\/\.next\/standalone \&\& HOSTNAME=0.0.0.0/g' "${LOGIN_DIR}/apps/login/package.json"
# Create api.env file
cat > "${CONFIG_DIR}/api.env" <<EOF
ZITADEL_MASTERKEY=${MASTERKEY}
ZITADEL_DATABASE_POSTGRES_HOST=localhost
ZITADEL_DATABASE_POSTGRES_PORT=5432
ZITADEL_DATABASE_POSTGRES_DATABASE=${DB_NAME}
ZITADEL_DATABASE_POSTGRES_USER_USERNAME=${DB_USER}
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=${DB_PASSWORD}
ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=disable
ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=postgres
ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD=${POSTGRES_ADMIN_PASSWORD}
ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable
ZITADEL_EXTERNALSECURE=false
EOF
# Set secure permissions
chmod 600 "${CONFIG_DIR}/api.env"
chown "${ZITADEL_USER}:${ZITADEL_GROUP}" "${CONFIG_DIR}/api.env"
msg_ok "Installed Zitadel"
msg_info "Creating Services"
# Create API service
cat > /etc/systemd/system/zitadel-api.service <<EOF
[Unit]
Description=ZITADEL API Server
After=network.target postgresql.service
Requires=postgresql.service
[Service]
Type=simple
User=${ZITADEL_USER}
Group=${ZITADEL_GROUP}
WorkingDirectory=${ZITADEL_DIR}
EnvironmentFile=${CONFIG_DIR}/api.env
Environment="PATH=/usr/local/bin:/usr/local/go/bin:/usr/bin:/bin"
ExecStart=${ZITADEL_DIR}/zitadel start --config ${CONFIG_DIR}/config.yaml --masterkey \${ZITADEL_MASTERKEY}
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
# Create Login V2 service
cat > /etc/systemd/system/zitadel-login.service <<EOF
[Unit]
Description=ZITADEL Login V2 Service
After=network.target zitadel-api.service
Requires=zitadel-api.service
[Service]
Type=simple
User=${ZITADEL_USER}
Group=${ZITADEL_GROUP}
WorkingDirectory=${LOGIN_DIR}/apps/login
EnvironmentFile=${CONFIG_DIR}/login.env
Environment="PATH=/usr/local/bin:/usr/bin:/bin"
Environment="NODE_ENV=production"
ExecStart=node ${LOGIN_DIR}/apps/login/server.js
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
# Reload systemd
systemctl daemon-reload
# Enable and start API service
systemctl enable -q --now zitadel-api.service
# Wait for API to start
sleep 10
# Enable and start Login service
systemctl enable -q --now zitadel-login.service
msg_ok "Created Services"
msg_info "Saving Credentials"
# Create credentials file
cat > "${CONFIG_DIR}/INSTALLATION_INFO.txt" <<EOF
################################################################################
# ZITADEL Installation Information
# Generated: $(date)
################################################################################
SERVER INFORMATION:
-------------------
Server IP: ${SERVER_IP}
API Port: ${API_PORT}
Login Port: ${LOGIN_PORT}
ACCESS URLS:
------------
Management Console: http://${SERVER_IP}:${API_PORT}/ui/console
Login V2 UI: http://${SERVER_IP}:${LOGIN_PORT}/ui/v2/login
API Endpoint: http://${SERVER_IP}:${API_PORT}
DEFAULT ADMIN CREDENTIALS:
--------------------------
Username: zitadel-admin@zitadel.localhost
Password: Password1!
IMPORTANT: Change this password immediately after first login!
DATABASE CREDENTIALS:
---------------------
Database Name: ${DB_NAME}
Database User: ${DB_USER}
Database Password: ${DB_PASSWORD}
PostgreSQL Admin Password: ${POSTGRES_ADMIN_PASSWORD}
SECURITY:
---------
Master Key: ${MASTERKEY}
IMPORTANT: Keep these credentials secure and backup this file!
VERIFICATION:
-------------
1. Check API health:
curl http://${SERVER_IP}:${API_PORT}/debug/healthz
2. Access Management Console:
http://${SERVER_IP}:${API_PORT}/ui/console
3. Login with admin credentials above
DATABASE INFORMATION:
--------------------
The database and user are automatically created by ZITADEL on first startup.
ZITADEL uses the admin credentials to create:
- Database: ${DB_NAME}
- User: ${DB_USER}
- Schemas: eventstore, projections, system
PRODUCTION NOTES:
-----------------
1. This installation uses HTTP (not HTTPS) for simplicity
2. For production with HTTPS:
- Set ExternalSecure: true in config.yaml
- Configure TLS certificates
- Update firewall rules for port 443
3. Change all default passwords immediately
4. Set up regular database backups
5. Configure proper monitoring and alerting
6. Review and harden PostgreSQL security settings
BACKUP COMMANDS:
----------------
Database backup:
PGPASSWORD=${DB_PASSWORD} pg_dump -h localhost -U ${DB_USER} ${DB_NAME} > zitadel_backup_\$(date +%Y%m%d).sql
Database restore:
PGPASSWORD=${DB_PASSWORD} psql -h localhost -U ${DB_USER} ${DB_NAME} < zitadel_backup_YYYYMMDD.sql
################################################################################
EOF
chmod 600 "${CONFIG_DIR}/INSTALLATION_INFO.txt"
chown "${ZITADEL_USER}:${ZITADEL_GROUP}" "${CONFIG_DIR}/INSTALLATION_INFO.txt"
cp ${ZITADEL_DIR}/admin.pat ${CONFIG_DIR}/admin.pat.BAK
cp ${ZITADEL_DIR}/login-client.pat ${CONFIG_DIR}/login-client.pat.BAK
msg_ok "Saved Credentials"
msg_info "Create zitadel-rerun.sh"
cat <<EOF >~/zitadel-rerun.sh
systemctl stop zitadel
timeout --kill-after=5s 15s zitadel setup --masterkeyFile ${CONFIG_DIR}/.masterkey --config ${CONFIG_DIR}/config.yaml"
systemctl restart zitadel
EOF
msg_ok "Bash script for rerunning Zitadel after changing Zitadel config.yaml"
motd_ssh
customize
cleanup_lxc