Zammad
Web-based open source helpdesk and customer support system
Alternative to: zendesk, freshdesk, front, help scout
Zammad is a web-based, open-source helpdesk and customer support platform that streamlines customer communication across channels like email, chat, telephone, and social media into a single shared inbox. It gives support teams ticket automation, SLAs, a knowledge base, and reporting, offering a self-hosted alternative to Zendesk, Freshdesk, and Front.
Zammad Docker Compose example
Self-host Zammad on your own server, homelab, or VPS starting from this Docker Compose example.
It runs Zammad in Docker containers using the official ghcr.io/zammad/zammad:latest, memcached:alpine, postgres:17-alpine, redis:alpine images, with persistent volumes and automatic restarts preconfigured.
Review the environment variables and adjust them to your setup, save the file as compose.yml (or docker-compose.yml), and start the stack with docker compose up -d.
x-shared:
zammad-service: &zammad-service
image: ghcr.io/zammad/zammad:latest
restart: unless-stopped
environment: &zammad-environment
# Memcached endpoint used for Zammad's Rails cache
MEMCACHE_SERVERS: "zammad-memcached:11211"
# PostgreSQL connection (internal to the compose network)
POSTGRESQL_HOST: "zammad-postgresql"
POSTGRESQL_PORT: "5432"
POSTGRESQL_USER: "zammad"
POSTGRESQL_PASS: "zammad"
POSTGRESQL_DB: "zammad_production"
POSTGRESQL_OPTIONS: "?pool=50"
# Redis endpoint used for background jobs and websocket sessions
REDIS_URL: "redis://zammad-redis:6379"
# Elasticsearch is optional; disabled here so the stack runs without it
ELASTICSEARCH_ENABLED: "false"
# Public scheme used when Zammad builds absolute links (http or https)
ZAMMAD_HTTP_TYPE: "https"
# Public fully-qualified domain name Zammad is served on
ZAMMAD_FQDN: "changeme"
# Timezone
TZ: "UTC"
volumes:
- zammad-storage:/opt/zammad/storage
depends_on:
zammad-memcached:
condition: service_healthy
zammad-postgresql:
condition: service_healthy
zammad-redis:
condition: service_healthy
services:
zammad-init:
<<: *zammad-service
command: ["zammad-init"]
restart: on-failure
user: 0:0
depends_on:
zammad-postgresql:
condition: service_healthy
zammad-memcached:
image: memcached:alpine
command: memcached -m 256M
restart: unless-stopped
healthcheck:
test: ["CMD", "nc", "-z", "127.0.0.1", "11211"]
interval: 10s
timeout: 5s
start_period: 10s
retries: 5
zammad-nginx:
<<: *zammad-service
command: ["zammad-nginx"]
depends_on:
zammad-railsserver:
condition: service_healthy
zammad-postgresql:
image: postgres:17-alpine
restart: unless-stopped
environment:
# Database created on first start
POSTGRES_DB: "zammad_production"
# Database owner role
POSTGRES_USER: "zammad"
# Password for the database owner role
POSTGRES_PASSWORD: "zammad"
volumes:
- postgresql-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U zammad -d zammad_production"]
interval: 10s
timeout: 5s
start_period: 60s
retries: 5
zammad-railsserver:
<<: *zammad-service
command: ["zammad-railsserver"]
healthcheck:
test: ["CMD", "curl", "-sf", "http://127.0.0.1:3000"]
interval: 30s
timeout: 5s
start_period: 120s
retries: 3
zammad-redis:
image: redis:alpine
restart: unless-stopped
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
start_period: 10s
retries: 5
zammad-scheduler:
<<: *zammad-service
command: ["zammad-scheduler"]
zammad-websocket:
<<: *zammad-service
command: ["zammad-websocket"]
volumes:
postgresql-data:
redis-data:
zammad-storage:
Values set to changeme are required — replace them with your own
values before starting Zammad.
Prefer a managed setup? WinterFlow installs, configures, and updates Zammad for you using this same Docker Compose configuration.