Zammad Helpdesk Installation

Zammad is an open-source helpdesk and ticketing system providing customer support management with agent collaboration, ticket automation, and customer self-service portals. With integrated email, chat, and phone support, Zammad enables organizations to provide excellent customer service. This guide covers Docker deployment, Elasticsearch setup, PostgreSQL configuration, SSL setup, and email channel management.

Table of Contents

Prerequisites

Ensure you have:

  • Ubuntu 20.04 LTS or later
  • Root or sudo access
  • A registered domain name
  • Minimum 4GB RAM (8GB+ recommended)
  • 50GB available disk space
  • Basic Linux administration knowledge

Update system:

sudo apt update && sudo apt upgrade -y

System Requirements

Verify system specifications:

Check OS version:

cat /etc/os-release
uname -m

Check available resources:

free -h
df -h

Docker Installation

Install Docker and Docker Compose:

sudo apt install -y docker.io docker-compose

Add user to docker group:

sudo usermod -aG docker $USER
newgrp docker

Verify installation:

docker --version
docker-compose --version

Start Docker:

sudo systemctl start docker
sudo systemctl enable docker

Elasticsearch Setup

Create Elasticsearch data directory:

sudo mkdir -p /var/lib/elasticsearch
sudo chown -R $USER:$USER /var/lib/elasticsearch

Create Elasticsearch container:

docker run -d \
  --name elasticsearch \
  -e "discovery.type=single-node" \
  -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
  -v /var/lib/elasticsearch:/usr/share/elasticsearch/data \
  -p 9200:9200 \
  docker.elastic.co/elasticsearch/elasticsearch:7.15.0

Verify Elasticsearch:

docker ps | grep elasticsearch
curl http://localhost:9200/_cluster/health

PostgreSQL Configuration

Create PostgreSQL data directory:

sudo mkdir -p /var/lib/postgresql-zammad
sudo chown -R $USER:$USER /var/lib/postgresql-zammad

Create PostgreSQL container:

docker run -d \
  --name postgres-zammad \
  -e POSTGRES_DB=zammad \
  -e POSTGRES_USER=zammad \
  -e POSTGRES_PASSWORD=SecurePassword123! \
  -v /var/lib/postgresql-zammad:/var/lib/postgresql/data \
  postgres:13-alpine

Verify PostgreSQL:

docker ps | grep postgres

Zammad Deployment

Create Zammad directory:

mkdir -p /opt/zammad
cd /opt/zammad

Create docker-compose.yml:

nano docker-compose.yml

Add configuration:

version: '3.7'

services:
  zammad:
    image: zammad/zammad:latest
    restart: always
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://zammad:SecurePassword123!@postgres-zammad:5432/zammad
      ELASTICSEARCH_HOST: elasticsearch
      ELASTICSEARCH_PORT: 9200
      MEMCACHE_SERVERS: memcache:11211
      POSTGRES_DB: zammad
      POSTGRES_USER: zammad
      POSTGRES_PASSWORD: SecurePassword123!
      RAILS_ENV: production
      RAILS_LOG_TO_STDOUT: "true"
    volumes:
      - /opt/zammad/data:/opt/zammad/var
    depends_on:
      - postgres-zammad
      - elasticsearch
      - memcache
    networks:
      - zammad

  zammad-scheduler:
    image: zammad/zammad:latest
    restart: always
    command: ["bundle", "exec", "script/scheduler.rb"]
    environment:
      DATABASE_URL: postgresql://zammad:SecurePassword123!@postgres-zammad:5432/zammad
      ELASTICSEARCH_HOST: elasticsearch
      ELASTICSEARCH_PORT: 9200
      MEMCACHE_SERVERS: memcache:11211
      POSTGRES_DB: zammad
      POSTGRES_USER: zammad
      POSTGRES_PASSWORD: SecurePassword123!
      RAILS_ENV: production
    volumes:
      - /opt/zammad/data:/opt/zammad/var
    depends_on:
      - postgres-zammad
      - elasticsearch
      - memcache
    networks:
      - zammad

  postgres-zammad:
    image: postgres:13-alpine
    restart: always
    environment:
      POSTGRES_DB: zammad
      POSTGRES_USER: zammad
      POSTGRES_PASSWORD: SecurePassword123!
    volumes:
      - /var/lib/postgresql-zammad:/var/lib/postgresql/data
    networks:
      - zammad

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0
    restart: always
    environment:
      discovery.type: single-node
      ES_JAVA_OPTS: "-Xms512m -Xmx512m"
    volumes:
      - /var/lib/elasticsearch:/usr/share/elasticsearch/data
    networks:
      - zammad

  memcache:
    image: memcached:alpine
    restart: always
    networks:
      - zammad

networks:
  zammad:
    driver: bridge

Create data directory:

mkdir -p /opt/zammad/data

Start Zammad containers:

docker-compose up -d

Initialize database:

docker-compose exec zammad bundle exec rake db:migrate
docker-compose exec zammad bundle exec rake zammad:setup

Verify containers:

docker-compose ps
docker-compose logs -f zammad

Wait for initialization to complete.

Nginx Configuration

Install Nginx:

sudo apt install -y nginx

Create Nginx configuration:

sudo nano /etc/nginx/sites-available/zammad

Add configuration:

upstream zammad {
    server localhost:3000;
}

server {
    listen 80;
    listen [::]:80;
    server_name support.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name support.example.com;

    ssl_certificate /etc/letsencrypt/live/support.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/support.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    client_max_body_size 100M;

    location / {
        proxy_pass http://zammad;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_buffering off;
    }
}

Enable site:

sudo ln -s /etc/nginx/sites-available/zammad /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl start nginx
sudo systemctl enable nginx

SSL Certificate Setup

Install Certbot:

sudo apt install -y certbot python3-certbot-nginx

Obtain SSL certificate:

sudo certbot certonly --standalone -d support.example.com

Verify certificate:

sudo openssl x509 -in /etc/letsencrypt/live/support.example.com/fullchain.pem -noout -dates

Set up auto-renewal:

sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

Email Channel Configuration

Access Zammad:

Navigate to https://support.example.com

Complete admin setup:

  1. Create admin account
  2. Configure organization name
  3. Configure email domain

Configure email channel:

  1. Go to Admin → Channels → Email

  2. Click "Add Channel"

  3. Configure IMAP:

    • IMAP host
    • Username/password
    • Folder to monitor
  4. Configure SMTP:

    • SMTP host
    • Username/password
    • Sender email

Test email channel:

  1. Send test email to configured address
  2. Verify ticket creation
  3. Monitor mail logs

Admin Configuration

Configure admin settings:

  1. Admin → Settings

    • System name
    • Logo
    • Email configuration
    • SLA settings
  2. Admin → Groups

    • Create support teams
    • Assign agents to groups
  3. Admin → Users

    • Create agent accounts
    • Set roles and permissions
  4. Admin → Triggers

    • Set up automation rules
    • Configure SLA escalations

Configure customer portal:

  1. Admin → Settings → System
    • Enable customer self-service
    • Configure knowledge base

Backup Strategy

Create backup script:

sudo nano /usr/local/bin/zammad-backup.sh

Add:

#!/bin/bash

BACKUP_DIR="/backups/zammad"
ZAMMAD_DIR="/opt/zammad"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR

# Database backup
docker exec postgres-zammad pg_dump -U zammad zammad | gzip > "$BACKUP_DIR/zammad-db-$DATE.sql.gz"

# Data backup
tar -czf "$BACKUP_DIR/zammad-data-$DATE.tar.gz" "$ZAMMAD_DIR/data"

# Keep only 30 days
find $BACKUP_DIR -type f -mtime +30 -delete

echo "Backup completed: $DATE"

Make executable:

sudo chmod +x /usr/local/bin/zammad-backup.sh

Schedule daily backups:

sudo crontab -e

Add:

0 2 * * * /usr/local/bin/zammad-backup.sh >> /var/log/zammad-backup.log 2>&1

Update Zammad:

cd /opt/zammad
docker-compose pull
docker-compose down
docker-compose up -d
docker-compose exec zammad bundle exec rake db:migrate

Monitor logs:

docker-compose logs -f zammad

Conclusion

Zammad is now fully deployed as a comprehensive helpdesk solution. With PostgreSQL database, Elasticsearch search, Docker containerization, Nginx reverse proxy, and SSL encryption, you have a robust customer support platform. Configure email channels, create agent teams, and establish SLA policies. Automate support workflows and monitor ticket metrics. Regular backups ensure data protection and business continuity. Zammad enables organizations to provide excellent, scalable customer support.