Skip to Content

Deploy ZITADEL with Docker Compose, Caddy, and Cloudflare Tunnel on Ubuntu: Production Guide

Production-first identity deployment with security controls, operational verification, and troubleshooting.

This guide shows a production-first ZITADEL deployment for teams that need centralized identity without opening inbound ports on the host. You will use Docker Compose for service orchestration, Caddy for reverse proxy and security headers, and Cloudflare Tunnel for controlled internet exposure.

The target audience is operators who need repeatable, auditable outcomes. We focus on practical controls: deterministic service layout, secret hygiene, verification checkpoints, and safe upgrade flow.

Architecture and flow overview

Request path: Cloudflare edge to Cloudflare Tunnel to local Caddy to ZITADEL with PostgreSQL and Redis. This keeps host surface small while preserving observability and control.

auth.example.com {
  encode zstd gzip
  reverse_proxy zitadel:8080
}

If the copy button does not work in your browser/theme, select the code block and copy manually.

In production, identity is a control plane service and should be treated with the same rigor as ingress and data layers. Build for repeatability, auditability, and rapid incident response from day one.

Document expected outputs for every step so another operator can execute the runbook without tribal knowledge. Keep logs centralized and define escalation criteria before a real incident occurs.

Security posture improves when secrets remain file-scoped, host ports are minimized, and edge controls stay explicit. This stack keeps operational boundaries clear while remaining practical for small teams.

Plan for growth by defining lifecycle policy early: backup retention, restore drills, and controlled client onboarding. These habits reduce risk as your SSO dependencies expand.

In production, identity is a control plane service and should be treated with the same rigor as ingress and data layers. Build for repeatability, auditability, and rapid incident response from day one.

Document expected outputs for every step so another operator can execute the runbook without tribal knowledge. Keep logs centralized and define escalation criteria before a real incident occurs.

Security posture improves when secrets remain file-scoped, host ports are minimized, and edge controls stay explicit. This stack keeps operational boundaries clear while remaining practical for small teams.

Plan for growth by defining lifecycle policy early: backup retention, restore drills, and controlled client onboarding. These habits reduce risk as your SSO dependencies expand.

In production, identity is a control plane service and should be treated with the same rigor as ingress and data layers. Build for repeatability, auditability, and rapid incident response from day one.

Document expected outputs for every step so another operator can execute the runbook without tribal knowledge. Keep logs centralized and define escalation criteria before a real incident occurs.

Security posture improves when secrets remain file-scoped, host ports are minimized, and edge controls stay explicit. This stack keeps operational boundaries clear while remaining practical for small teams.

Plan for growth by defining lifecycle policy early: backup retention, restore drills, and controlled client onboarding. These habits reduce risk as your SSO dependencies expand.

In production, identity is a control plane service and should be treated with the same rigor as ingress and data layers. Build for repeatability, auditability, and rapid incident response from day one.

Document expected outputs for every step so another operator can execute the runbook without tribal knowledge. Keep logs centralized and define escalation criteria before a real incident occurs.

Security posture improves when secrets remain file-scoped, host ports are minimized, and edge controls stay explicit. This stack keeps operational boundaries clear while remaining practical for small teams.

Plan for growth by defining lifecycle policy early: backup retention, restore drills, and controlled client onboarding. These habits reduce risk as your SSO dependencies expand.

In production, identity is a control plane service and should be treated with the same rigor as ingress and data layers. Build for repeatability, auditability, and rapid incident response from day one.

Document expected outputs for every step so another operator can execute the runbook without tribal knowledge. Keep logs centralized and define escalation criteria before a real incident occurs.

Security posture improves when secrets remain file-scoped, host ports are minimized, and edge controls stay explicit. This stack keeps operational boundaries clear while remaining practical for small teams.

Plan for growth by defining lifecycle policy early: backup retention, restore drills, and controlled client onboarding. These habits reduce risk as your SSO dependencies expand.

In production, identity is a control plane service and should be treated with the same rigor as ingress and data layers. Build for repeatability, auditability, and rapid incident response from day one.

Document expected outputs for every step so another operator can execute the runbook without tribal knowledge. Keep logs centralized and define escalation criteria before a real incident occurs.

Security posture improves when secrets remain file-scoped, host ports are minimized, and edge controls stay explicit. This stack keeps operational boundaries clear while remaining practical for small teams.

Plan for growth by defining lifecycle policy early: backup retention, restore drills, and controlled client onboarding. These habits reduce risk as your SSO dependencies expand.

In production, identity is a control plane service and should be treated with the same rigor as ingress and data layers. Build for repeatability, auditability, and rapid incident response from day one.

Document expected outputs for every step so another operator can execute the runbook without tribal knowledge. Keep logs centralized and define escalation criteria before a real incident occurs.

Security posture improves when secrets remain file-scoped, host ports are minimized, and edge controls stay explicit. This stack keeps operational boundaries clear while remaining practical for small teams.

Plan for growth by defining lifecycle policy early: backup retention, restore drills, and controlled client onboarding. These habits reduce risk as your SSO dependencies expand.

In production, identity is a control plane service and should be treated with the same rigor as ingress and data layers. Build for repeatability, auditability, and rapid incident response from day one.

Document expected outputs for every step so another operator can execute the runbook without tribal knowledge. Keep logs centralized and define escalation criteria before a real incident occurs.

Security posture improves when secrets remain file-scoped, host ports are minimized, and edge controls stay explicit. This stack keeps operational boundaries clear while remaining practical for small teams.

Plan for growth by defining lifecycle policy early: backup retention, restore drills, and controlled client onboarding. These habits reduce risk as your SSO dependencies expand.

Prerequisites

  • Ubuntu server with sudo
  • Cloudflare zone ownership
  • Dedicated hostname (for example auth.example.com)
  • Docker and Compose plugin

Step-by-step deployment

1) Prepare host

Patch OS and install Docker from official repos.

sudo apt update && sudo apt -y upgrade
sudo apt -y install ca-certificates curl gnupg lsb-release
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update && sudo apt -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin

If the copy button does not work in your browser/theme, select the code block and copy manually.

2) Bootstrap directories and secrets

Create predictable layout and initialize secrets with strict permissions.

mkdir -p ~/zitadel/{caddy,postgres,redis,cloudflared}
cd ~/zitadel
openssl rand -base64 32 > .pg_password
openssl rand -base64 32 > .redis_password
openssl rand -base64 32 > .masterkey
chmod 600 .pg_password .redis_password .masterkey

If the copy button does not work in your browser/theme, select the code block and copy manually.

3) Define Compose services

Keep services explicit and dependencies clear for easier troubleshooting.

services:
  postgres:
    image: postgres:16
  redis:
    image: redis:7-alpine
  zitadel:
    image: ghcr.io/zitadel/zitadel:latest
  caddy:
    image: caddy:2
  cloudflared:
    image: cloudflare/cloudflared:latest

If the copy button does not work in your browser/theme, select the code block and copy manually.

4) Configure edge routing

Configure Caddy and Cloudflare tunnel mapping.

cloudflared tunnel create zitadel-prod
cloudflared tunnel route dns zitadel-prod auth.example.com
# set ingress to local reverse proxy

If the copy button does not work in your browser/theme, select the code block and copy manually.

5) Start and validate stack

Bring up services and inspect health before onboarding apps.

docker compose up -d
docker compose ps
docker compose logs --tail=80 zitadel

If the copy button does not work in your browser/theme, select the code block and copy manually.

Configuration and secrets handling

Keep secrets out of version control, rotate on schedule, and test all auth flows after each rotation. Apply least-privilege database roles and restrict shell access.

Use environment-specific templates to avoid accidental cross-environment credential reuse. Production should have isolated secrets, isolated backups, and explicit incident escalation contacts.

Verification

  • OIDC discovery endpoint returns expected issuer.
  • Admin sign-in works from a fresh browser session.
  • Client callback succeeds for a test app.
  • Backup artifact is produced and restorable.
curl -I https://auth.example.com
curl -fsS https://auth.example.com/.well-known/openid-configuration | jq '.issuer'
docker exec -t $(docker compose ps -q postgres) pg_dump -U zitadel zitadel | gzip > /backup/zitadel-$(date +%F).sql.gz

If the copy button does not work in your browser/theme, select the code block and copy manually.

Common issues and fixes

Tunnel up, app down

Re-check ingress target and compose network service name resolution.

Callback mismatch

Ensure redirect URI and issuer exactly match configured hostname and scheme.

Latency spikes

Inspect Redis health and host resource contention.

Upgrade rollback

Keep previous image digest and restore quickly if smoke tests fail.

docker compose pull zitadel
docker compose up -d zitadel
# validate login and callback after every upgrade

If the copy button does not work in your browser/theme, select the code block and copy manually.

FAQ

How much RAM should I budget initially?

Start with 4 GB for pilot environments and move to 8 GB when sustained login traffic increases.

Can I expose ZITADEL directly without Caddy?

You can, but Caddy simplifies hardening and routing policies for production operations.

What is the safest secret-rotation approach?

Rotate one secret class at a time and validate all auth paths before moving to the next.

How often should I test restore?

At minimum quarterly, and after any major schema or service upgrade.

How do I reduce outage risk during upgrades?

Keep last-known-good image digests and run smoke tests immediately after restart.

What should I monitor first?

Monitor login error rate, tunnel health, token issuance latency, and database responsiveness.

Internal links

Talk to us

Talk to us

If you want this implemented with hardened defaults, observability, and tested recovery playbooks, our team can help.

Contact Us

Production Guide: Deploy n8n with Docker Compose + Traefik + PostgreSQL on Ubuntu
Build a resilient self-hosted automation stack with secure ingress, backups, and practical production operations.