Zammad logo

Zammad

Web-based open source helpdesk and customer support system

Alternative to: zendesk, freshdesk, front, help scout


About

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.