Zammad is an open-source helpdesk and ticketing system written in Ruby on Rails. It consolidates customer support requests from email, phone, chat, social media (Facebook, Telegram, Twitter), and web forms into a single web-based interface. Zammad stores its data in PostgreSQL and uses Elasticsearch for full-text search across tickets, attachments, and knowledge base articles.

This guide walks through installing Zammad helpdesk on Rocky Linux 10 or AlmaLinux 10. We cover Elasticsearch, PostgreSQL, the Zammad application itself, Nginx reverse proxy with Let’s Encrypt SSL, email channel configuration, LDAP integration, SLA management, branding, and backups.

Prerequisites

  • A server running Rocky Linux 10 or AlmaLinux 10 with at least 4 GB RAM and 2 CPU cores
  • Root or sudo access
  • A fully qualified domain name (FQDN) pointing to the server IP – for example support.example.com
  • Ports 80 (HTTP), 443 (HTTPS), and 25/587 (SMTP) open in the firewall
  • SELinux set to permissive or appropriate booleans configured

Start by updating the system packages and setting the hostname.

sudo dnf update -y
sudo hostnamectl set-hostname support.example.com

Step 1: Install Elasticsearch on Rocky Linux 10 / AlmaLinux 10

Zammad requires Elasticsearch for its full-text search engine. Zammad 6.x supports Elasticsearch 8.x. Import the Elasticsearch GPG key and add the repository.

sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch

Create the repository file.

echo "[elasticsearch-8.x]
name=Elasticsearch repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md" | sudo tee /etc/yum.repos.d/elasticsearch-8.x.repo

Install Elasticsearch.

sudo dnf install -y elasticsearch

Configure Elasticsearch for Zammad

Zammad connects to Elasticsearch over HTTP on localhost, so we need to disable the security features that Elasticsearch 8.x enables by default. Edit the Elasticsearch configuration file.

sudo vi /etc/elasticsearch/elasticsearch.yml

Set the following values. If the lines already exist, update them. Otherwise, add them at the end of the file.

# Bind to localhost only
network.host: 127.0.0.1
http.port: 9200

# Disable security (Zammad connects locally)
xpack.security.enabled: false
xpack.security.enrollment.enabled: false
xpack.security.http.ssl.enabled: false
xpack.security.transport.ssl.enabled: false

# Single node setup
discovery.type: single-node

Install the Elasticsearch ingest-attachment plugin required by Zammad for indexing file attachments.

sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install ingest-attachment

Start and enable Elasticsearch.

sudo systemctl enable --now elasticsearch

Verify that Elasticsearch is running and responding on port 9200.

curl -s http://localhost:9200 | python3 -m json.tool

Expected output shows the cluster name, version number, and tagline “You Know, for Search”.

{
    "name": "support.example.com",
    "cluster_name": "elasticsearch",
    "cluster_uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "version": {
        "number": "8.17.x",
        ...
    },
    "tagline": "You Know, for Search"
}

Step 2: Install PostgreSQL Database

Zammad uses PostgreSQL as its primary database backend. Install PostgreSQL from the default Rocky Linux 10 / AlmaLinux 10 repositories.

sudo dnf install -y postgresql-server postgresql-contrib

Initialize and start the PostgreSQL database cluster.

sudo postgresql-setup --initdb
sudo systemctl enable --now postgresql

Confirm the database service is active.

sudo systemctl status postgresql

The output should show active (running). PostgreSQL is now ready. The Zammad package installer will automatically create the required database and user during installation.

Step 3: Add Zammad Repository and Install Zammad

Zammad provides an official RPM repository for RHEL-based systems. Import the GPG key and add the repository.

sudo rpm --import https://dl.packager.io/srv/zammad/zammad/key

Add the Zammad stable repository for Enterprise Linux 10.

echo "[zammad]
name=Repository for zammad/zammad application
baseurl=https://dl.packager.io/srv/rpm/zammad/zammad/stable/el/10/\$basearch
gpgcheck=1
gpgkey=https://dl.packager.io/srv/zammad/zammad/key
enabled=1" | sudo tee /etc/yum.repos.d/zammad.repo

Install Zammad. This pulls in Ruby, Nginx, and all dependencies automatically.

sudo dnf install -y zammad

The installation process takes several minutes. It creates the zammad system user, sets up the PostgreSQL database, runs migrations, and precompiles assets. Once complete, verify the Zammad services are running.

sudo systemctl status zammad-web zammad-worker zammad-websocket

All three services should show active (running). If any service failed to start, check the logs with journalctl -u zammad-web for troubleshooting details.

Connect Zammad to Elasticsearch

Tell Zammad where to find Elasticsearch and rebuild the search index.

sudo zammad run rails r "Setting.set('es_url', 'http://localhost:9200')"

Build the initial search index. This runs in the background and may take a few minutes on a fresh install.

sudo zammad run rake zammad:searchindex:rebuild

Step 4: Configure Nginx Reverse Proxy for Zammad

The Zammad package installs Nginx and drops a default configuration file. We need to customize it for our domain. First, remove the default Nginx server block.

sudo rm -f /etc/nginx/conf.d/default.conf

Edit the Zammad Nginx configuration file.

sudo vi /etc/nginx/conf.d/zammad.conf

Replace the server_name directive with your FQDN. The key section to update is shown below.

server {
    listen 80;
    server_name support.example.com;

    # Redirect all HTTP to HTTPS (enabled after SSL setup)
    # return 301 https://$server_name$request_uri;

    root /opt/zammad/public;
    access_log /var/log/nginx/zammad.access.log;
    error_log /var/log/nginx/zammad.error.log;

    client_max_body_size 50M;

    location /ws {
        proxy_pass http://127.0.0.1:6042;
        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_read_timeout 86400;
    }

    location / {
        try_files $uri @proxy;
    }

    location @proxy {
        proxy_pass http://127.0.0.1:3000;
        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;
    }
}

Test the Nginx configuration and restart the service.

sudo nginx -t
sudo systemctl restart nginx

Configure Firewall Rules

Open HTTP and HTTPS ports in firewalld.

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Set SELinux Permissions

If SELinux is enforcing, allow Nginx to connect to upstream services and send emails.

sudo setsebool -P httpd_can_network_connect 1
sudo setsebool -P httpd_can_sendmail 1

Verify the booleans are set.

getsebool httpd_can_network_connect httpd_can_sendmail

Both should return on.

Step 5: Secure Zammad with Let’s Encrypt SSL

Install Certbot and the Nginx plugin to obtain a free Let’s Encrypt SSL certificate.

sudo dnf install -y certbot python3-certbot-nginx

Request the certificate. Replace support.example.com with your actual domain and provide a valid email address.

sudo certbot --nginx -d support.example.com --non-interactive --agree-tos -m [email protected]

Certbot modifies the Nginx configuration to add SSL listeners, certificate paths, and redirects HTTP to HTTPS. Verify the changes were applied.

sudo nginx -t && sudo systemctl reload nginx

Enable the automatic renewal timer so the certificate renews before expiry.

sudo systemctl enable --now certbot-renew.timer

Test the renewal process with a dry run.

sudo certbot renew --dry-run

The output should confirm the renewal simulation succeeded. Access Zammad at https://support.example.com and confirm the browser shows a valid SSL certificate.

Step 6: Create the First Admin User

Open your browser and navigate to https://support.example.com. Zammad presents a setup wizard on first access. The wizard walks through these screens:

  • Admin account – Enter the full name, email, and password for the first administrator account. This user gets full system admin privileges
  • Organization name – Set your company or organization name. This appears in email notifications and the customer portal
  • Email notification – Configure the system email address and SMTP server (covered in the next step)
  • Channel setup – Connect your first email channel or skip to configure later

Complete each screen and click through to the dashboard. You now have administrative access to Zammad.

Step 7: Configure Email Channels (SMTP/IMAP)

Email is the primary channel for most helpdesk deployments. Zammad uses IMAP/POP3 to fetch incoming messages and SMTP to send outgoing replies. Navigate to the admin panel at Admin > Channels > Email.

Configure Outgoing Email (SMTP)

Click Settings > Email > Outbound and enter your SMTP server details.

  • SMTP Host: Your mail server address, e.g., smtp.example.com
  • SMTP Port: 587 (STARTTLS) or 465 (SSL/TLS)
  • Username: The email account username
  • Password: The email account password or app-specific password
  • SSL/STARTTLS: Enable based on your provider’s requirements

Click Save and then Test to send a verification email.

Configure Incoming Email (IMAP)

Go to Admin > Channels > Email > Accounts and click Add Account. Enter the IMAP connection details.

  • Host: imap.example.com
  • Port: 993 (SSL) or 143 (STARTTLS)
  • SSL: Yes
  • Username/Password: Mail account credentials
  • Folder: INBOX (or a specific folder to monitor)

After saving, Zammad polls the mailbox at regular intervals (default is every 2 minutes). Incoming emails automatically create new tickets or append to existing ones based on the email subject line threading.

Email Signature and Notification Templates

Configure email signatures under Admin > Channels > Email > Signatures. Each group can have its own signature. Customize notification templates under Admin > Channels > Email > Notifications to control what customers see when tickets are created, updated, or closed.

Step 8: LDAP / Active Directory Integration

Zammad supports LDAP and Active Directory for user authentication and automatic agent/customer provisioning. This eliminates the need to manage user accounts separately in Zammad.

Navigate to Admin > System > Integrations > LDAP and click Add Source. Enter the LDAP connection parameters.

  • Host: ldap://192.168.1.10 or ldaps://192.168.1.10 for SSL
  • Port: 389 (LDAP) or 636 (LDAPS)
  • Base DN: dc=example,dc=com
  • Bind User: cn=zammad-reader,ou=service-accounts,dc=example,dc=com
  • Bind Password: The service account password

After connecting, configure the user attribute mapping.

  • Login maps to sAMAccountName (AD) or uid (OpenLDAP)
  • First name maps to givenName
  • Last name maps to sn
  • Email maps to mail

LDAP Role Mapping

Map LDAP groups to Zammad roles to control access. For example, map CN=Helpdesk-Agents,OU=Groups,DC=example,DC=com to the Agent role, and CN=Helpdesk-Admins,OU=Groups,DC=example,DC=com to the Admin role. Users not matching any group mapping are created as customers by default.

Click Save and then Sync Now to perform the initial user import. Zammad syncs changes from LDAP on a scheduled interval, which you can configure under the same settings page.

Step 9: Ticket Workflows and SLA Management

Zammad provides automation tools to streamline ticket handling. Navigate to Admin > Manage to access these features.

Create Groups and Roles

Groups represent teams or departments – for example, “Technical Support”, “Billing”, and “Sales”. Create groups under Admin > Manage > Groups. Assign agents to groups so incoming tickets route to the correct team.

Roles define what actions users can perform. The default roles (Admin, Agent, Customer) cover most scenarios, but you can create custom roles under Admin > Manage > Roles for specialized permissions.

Configure SLAs

Service Level Agreements enforce response and resolution time commitments. Go to Admin > Manage > SLAs and click New SLA.

  • Name: e.g., “Standard Support SLA”
  • First response time: Maximum time before the first agent reply (e.g., 4 hours)
  • Update time: Maximum time between agent updates (e.g., 8 hours)
  • Solution time: Maximum time to resolve the ticket (e.g., 24 hours)
  • Business hours: Define working hours (e.g., Monday-Friday 08:00-18:00)
  • Conditions: Apply the SLA based on ticket priority, group, or organization

When SLA limits are about to be breached, Zammad highlights the ticket in the overview and can trigger escalation notifications.

Triggers and Automations

Triggers execute actions when tickets match specific conditions. Navigate to Admin > Manage > Triggers. Common trigger examples include:

  • Auto-assign tickets to a group based on keywords in the subject line
  • Set ticket priority to “high” when the sender is a VIP customer
  • Send an auto-reply confirming ticket creation
  • Close tickets automatically after 7 days of inactivity in “pending” state

Schedulers under Admin > Manage > Scheduler run periodic actions – for example, closing stale tickets or sending follow-up reminders. These execute on a cron-like schedule and work independently of triggers.

Step 10: Branding Customization

Customize Zammad’s appearance to match your organization’s branding under Admin > Settings > Branding.

  • Product Name: Change from “Zammad” to your company’s support brand name
  • Organization Logo: Upload your company logo (recommended size: 200×100 pixels, PNG or SVG)
  • Locale: Set the default language and timezone

For deeper customization, modify the customer portal appearance under Admin > Settings > Branding > Customer Interface. You can set a custom welcome message, change the color scheme, and add a custom CSS snippet for advanced theming.

The knowledge base section under Admin > Manage > Knowledge Base lets you create a public-facing FAQ section with its own color theme and logo. Customers can search the knowledge base before creating a ticket, reducing the volume of common questions.

Step 11: Backup and Restore Zammad

Zammad includes a built-in backup script that captures the database, attachments, and configuration. Run a manual backup.

sudo /opt/zammad/contrib/backup/zammad_backup.sh

By default, backups are stored in /var/tmp/zammad_backup. Check the backup directory after running the command.

ls -lh /var/tmp/zammad_backup/

The backup produces two files: a database dump and a files archive containing attachments and configuration.

Schedule Automated Backups

Add a cron job to run backups daily at 2 AM.

echo "0 2 * * * root /opt/zammad/contrib/backup/zammad_backup.sh" | sudo tee /etc/cron.d/zammad-backup

For production environments, copy the backup files to an offsite location using rsync, S3, or another remote storage solution. Keep at least 7 days of backups with a retention policy.

Restore from Backup

To restore Zammad from a backup, stop all Zammad services first.

sudo systemctl stop zammad

Run the restore script and point it to the backup directory.

sudo /opt/zammad/contrib/backup/zammad_restore.sh /var/tmp/zammad_backup

The script restores the database and files. Start the services again after restore completes.

sudo systemctl start zammad

Rebuild the Elasticsearch index after a restore to ensure search results are current.

sudo zammad run rake zammad:searchindex:rebuild

Zammad Maintenance Tips

Keep these operational tasks in mind for a production Zammad deployment.

  • Updates: Run sudo dnf update zammad to update Zammad. Always back up before upgrading and review the changelog for breaking changes
  • Logs: Application logs are in /opt/zammad/log/. The main log file is production.log
  • Performance: Zammad recommends at least 4 GB RAM. For deployments serving more than 40 agents, increase to 8 GB and add more Zammad worker processes
  • Elasticsearch index size: Monitor disk usage on the Elasticsearch data directory (/var/lib/elasticsearch/). Large ticket volumes with attachments can grow quickly
  • PostgreSQL vacuuming: The autovacuum daemon handles this by default, but monitor bloat on busy systems

Conclusion

Zammad is now running on Rocky Linux 10 / AlmaLinux 10 with PostgreSQL for data storage, Elasticsearch for search, Nginx as the reverse proxy, and Let’s Encrypt providing SSL encryption. The setup includes email channels, LDAP authentication, SLA policies, and automated backups.

For a production environment, monitor system resources with a tool like Prometheus or Zabbix, set up log rotation for Nginx and Zammad logs, and test your backup restore procedure periodically. Consider setting up a staging instance to test Zammad updates before applying them to production.

Related Guides

LEAVE A REPLY

Please enter your comment!
Please enter your name here