FAQ
Why Quadlets instead of docker-compose / podman-compose?
Quadlets translate directly into native systemd units, so Podman containers get systemd’s process supervision, dependency ordering, and boot/login integration for free — no separate compose daemon needs to keep running in the background, and it works cleanly rootless.
Can I really run this rootless?
Yes — that’s the point of this setup. Place the unit files in ~/.config/containers/systemd/, run
systemctl --user daemon-reload, and use loginctl enable-linger <user> so the services keep running even
when you’re logged out. See Usage for the full steps.
Where is my data actually stored?
In named Podman volumes: postgresql-data, redis-data, elasticsearch-data, and zammad-storage
(uploaded attachments and other app state, shared across the Rails/scheduler/websocket/nginx/backup
containers). Back these up, or rely on the bundled zammad-backup container and the BACKUP_DIR/
BACKUP_TIME/HOLD_DAYS settings in .env.
How do I update Zammad to a newer version?
Bump the image tag (currently ghcr.io/zammad/zammad:6.5.2-46) in every zammad-*.container file that
references it, then:
systemctl --user daemon-reload
systemctl --user restart zammad-pod.serviceElasticsearch is slow to start or using too much memory — what do I change?
Adjust ELASTICSEARCH_JAVA_OPTS in .env (the -Xms/-Xmx heap flags) to fit what your host can spare.
Can I disable Elasticsearch entirely?
Set ELASTICSEARCH_ENABLED=false in .env — Zammad falls back to database-only search.
Note
The shipped .env.example currently has a typo (ELASTICSEARCH_ENABLED=tru) — make sure you write the
full true/false in your own .env.
How do I put this behind a real domain?
Fill in either the reverse-proxy variables (VIRTUAL_HOST, LETSENCRYPT_HOST, LETSENCRYPT_EMAIL) or
CLOUDFLARE_TUNNEL_TOKEN in .env, depending on which approach you use, and route traffic to
NGINX_PORT/the pod’s published port.