# Deployment steps 1. create fresh project 2. take project CNAME domain (e.g. iq48ui9idn9id8kr0p70nl0icp0.prg1-zerops.zone) and use it as `ZITADEL_EXTERNALDOMAIN` 3. import services 4. `zcli push api` 5. `zcli push login` 6. setup routing ```text /ui/v2/login -> login:3000 / -> app:8080 ``` 7. login as `admin@zitadel.$ZITADEL_EXTERNALDOMAIN` # Import ```yaml #zeropsPreprocessor=on services: # PostgreSQL — Zitadel's backing store - hostname: db type: postgresql@18 mode: NON_HA # Zitadel API — Go binary on Ubuntu - hostname: api type: ubuntu@24.04 envSecrets: ZITADEL_MASTERKEY: <@generateRandomString(<32>)> ZITADEL_FIRSTINSTANCE_ORG_HUMAN_USERNAME: admin ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD: <@generateRandomString(<14>)>aZ1! ZITADEL_FIRSTINSTANCE_ORG_HUMAN_EMAIL: admin@example.com ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_USERNAME: loginclient ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_NAME: IAM_LOGIN_CLIENT ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_PAT_EXPIRATIONDATE: "2030-01-01T00:00:00Z" ZITADEL_FIRSTINSTANCE_LOGINCLIENTPATPATH: /tmp/login-client.pat # Must be filled beforehand. ZITADEL_EXTERNALDOMAIN: liqkls78uveo514fbj194ch6st0.prg1-zerops.zone # Login v2 — Next.js on Node.js - hostname: login type: nodejs@22 ``` # Zerops YAMLs ```yaml zerops: - setup: api build: os: ubuntu buildCommands: - wget -q https://github.com/zitadel/zitadel/releases/download/v4.13.1/zitadel-linux-amd64.tar.gz -O - | tar -xz - mv zitadel-linux-amd64/zitadel ./zitadel - chmod +x ./zitadel deployFiles: - ./ run: os: ubuntu envVariables: ZITADEL_DATABASE_POSTGRES_HOST: db ZITADEL_DATABASE_POSTGRES_PORT: ${db_port} ZITADEL_DATABASE_POSTGRES_DATABASE: ${db_dbName} ZITADEL_DATABASE_POSTGRES_USER_USERNAME: ${db_superUser} ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: ${db_superUserPassword} ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME: ${db_superUser} ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: ${db_superUserPassword} ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE: disable ZITADEL_EXTERNALPORT: "443" ZITADEL_EXTERNALSECURE: "true" ports: - port: 8080 httpSupport: true initCommands: - zsc execOnce zitadel-init -- ./zitadel init - zsc execOnce zitadel-setup-${appVersionId} -- ./zitadel setup --masterkey "${ZITADEL_MASTERKEY}" --tlsMode external - | if [ -f /tmp/login-client.pat ]; then cat /tmp/login-client.pat | zsc setSecretEnv ZITADEL_LOGIN_PAT - fi start: ./zitadel start --masterkey "${ZITADEL_MASTERKEY}" --tlsMode external healthCheck: httpGet: port: 8080 path: /debug/healthz - setup: login build: os: ubuntu base: nodejs@22 prepareCommands: - wget -q "https://github.com/google/go-containerregistry/releases/download/v0.20.3/go-containerregistry_Linux_x86_64.tar.gz" -O - | tar -xz crane - sudo mv crane /usr/local/bin/crane - sudo chmod +x /usr/local/bin/crane buildCommands: - crane export ghcr.io/zitadel/zitadel-login:latest - | tar -xf - -C /build/source app/ - ls -la deployFiles: - ./ run: os: ubuntu base: nodejs@22 envVariables: NEXT_PUBLIC_BASE_PATH: /ui/v2/login ZITADEL_API_URL: https://${api_ZITADEL_EXTERNALDOMAIN} ZITADEL_SERVICE_USER_TOKEN: ${api_ZITADEL_LOGIN_PAT} ports: - port: 3000 httpSupport: true start: node app/apps/login/server.js healthCheck: httpGet: port: 3000 path: /ui/v2/login/healthy ```