Persistent zitadel-init failure
Hello everyone,
I'm running into a persistent issue with my Zitadel Docker Compose setup and I'm hoping someone can spot what I'm missing.
The Situation:
I'm trying to deploy Zitadel and can successfully reach the UI on my domain. However, looking at the logs for my PostgreSQL container (db-1), I can see the initialization is failing and both zitadel-init and zitadel seems running .
I set up a docker-compose.yaml with de db postgres container, a zitadel-init container and a zitadel set-up container. I also configure nginx (TLS mode external).
Here the logs :
db-1 | 2025-09-23 17:45:28.429 UTC [1] LOG: database system is ready to accept connections
db-1 | 2025-09-23 17:45:32.852 UTC [56] ERROR: database "zitadel" already exists
db-1 | 2025-09-23 17:45:32.852 UTC [56] STATEMENT: CREATE DATABASE "zitadel"
zitadel-init-1 | time="2025-09-23T17:45:55Z" level=info msg="server is listening on [::]:8080" caller="/home/runner/work/zitadel/zitadel/cmd/start/start.go:508"
zitadel-1 | time="2025-09-23T17:45:54Z" level=info msg="server is listening on [::]:8080" caller="/home/runner/work/zitadel/zitadel/cmd/start/start.go:508"
My Question:
Could someone help me understand how to configurate my zitadel and what am I missing ?
2 Replies
Hi @Clementine, I'm an AI assistant for ZITADEL. While a team member reviews this question, I'll see if I can find relevant sources for your question.
Answer
Based on your logs, the message
- Set up Zitadel with Docker Compose
- Update and Scale ZITADE L To learn more, see the sources I considered: [1] Set up Zitadel with Docker Compose [2] Update and Scale ZITADEL [3] Configuration Options in ZITADEL Feel free to tag @Ask Inkeep with additional questions.
ERROR: database "zitadel" already exists
from your PostgreSQL container is normal if the initialization is being retried on an already existing database (1) . The ZITADEL init process is designed to be idempotent, so it checks if the database and required roles exist and skips creation if they do (2) .
If both zitadel-init
and zitadel
containers are running and you can access the UI, the core setup may already be complete. However, you should ensure:
- Your Docker Compose setup uses the recommended configuration, especially for environment variables and container dependencies (1) (3) .
- The init phase (zitadel-init
) should only run once and then exit; subsequent runs are unnecessary unless you're re-initializing the database (2) .
- The runtime phase (zitadel
) should start only after successful initialization .
You can review and adapt your docker-compose.yaml
to follow the official example, which ensures correct sequencing and environment configuration (1) (3) . If you continue to see errors, make sure that:
- The database user credentials are correct.
- No conflicting containers are trying to initialize the database at the same time.
- You are not running both zitadel-init
and zitadel
containers in parallel unless explicitly following a staged setup.
For reference:- Set up Zitadel with Docker Compose
- Update and Scale ZITADE L To learn more, see the sources I considered: [1] Set up Zitadel with Docker Compose [2] Update and Scale ZITADEL [3] Configuration Options in ZITADEL Feel free to tag @Ask Inkeep with additional questions.
ghcr.io/zitadel/zitadel:v2.53.1 "/app/zitadel start-…" 9 minutes ago Up 9 minutes 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp masterc-zitadel-1
ghcr.io/zitadel/zitadel:v2.53.1 "/app/zitadel start-…" 9 minutes ago Up 9 minutes masterc-zitadel-init-1
Both zitadel and zitadel-init cotainers are up, despite my separate configuration with start-from-init and the second start-from-setup.
Here my docker-compose file with password and user info modified :
services:
# Zitadel DB (PostgreSQL)
db:
restart: unless-stopped
image: postgres:17-alpine
user: postgres
environment:
POSTGRES_USER: postgresUser
POSTGRES_PASSWORD: MyPassword
POSTGRES_DB: zitadel
healthcheck:
test:
- CMD-SHELL
- pg_isready
- -U
- postgres
interval: 10s
timeout: 30s
retries: 5
start_period: 20s
networks:
- zitadel-isolated-net
ports:
- 5433:5432
volumes:
- 'data:/var/lib/postgresql/data:rw'
Zitadel IAM Service
zitadel-init:
image: ghcr.io/zitadel/zitadel:v2.53.1
entrypoint: ["/app/zitadel", "start-from-init", "--masterkey", "MyMasterKey32"]
environment:
ZITADEL_EXTERNALDOMAIN: my-domain.com
ZITADEL_EXTERNALPORT: 443
ZITADEL_EXTERNALSECURE: true # Important car Nginx système gère HTTPS
ZITADEL_TLS_ENABLED: false
# Database connection settings.
ZITADEL_DATABASE_POSTGRES_HOST: db
ZITADEL_DATABASE_POSTGRES_PORT: 5432
ZITADEL_DATABASE_POSTGRES_DATABASE: zitadel
ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME: postgresUser
ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: MyPassword
ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE: disable
ZITADEL_DATABASE_POSTGRES_USER_USERNAME: zitadelUser
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: MyPassword2
ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable
# Organisation et utilisateur admin
ZITADEL_FIRSTINSTANCE_ORG_NAME: me
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_USERNAME: admin
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD: MyAdminPassword!
# Debug
ZITADEL_LOG_LEVEL: info
networks:
- zitadel-isolated-net
depends_on:
db:
condition: service_healthy
The Main Zitadel Service
zitadel:
restart: unless-stopped
image: ghcr.io/zitadel/zitadel:v2.53.1
command: 'start-from-setup --masterkey MyMasterKey32 --tlsMode external'
environment:
ZITADEL_EXTERNALDOMAIN: my-domain.com
ZITADEL_EXTERNALPORT: 443
ZITADEL_EXTERNALSECURE: true
ZITADEL_TLS_ENABLED: false
ZITADEL_DATABASE_POSTGRES_HOST: db
ZITADEL_DATABASE_POSTGRES_PORT: 5432
ZITADEL_DATABASE_POSTGRES_DATABASE: zitadel
ZITADEL_DATABASE_POSTGRES_USER_USERNAME: zitadelUser
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: MyPassword2
ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable
ZITADEL_LOG_LEVEL: info
ports:
- "8080:8080"
networks:
- zitadel-isolated-net
depends_on:
db:
condition: service_healthy
networks:
zitadel-isolated-net:
driver: bridge
volumes:
data: