
Support email gets messy fast. A shared inbox works until you need assignment rules, SLAs, collision detection, and an audit trail you can trust.
If you want that control without per-agent pricing, you can run Zammad on a VPS and keep tickets and attachments on infrastructure you manage.
Zammad is an open-source helpdesk and ticketing system for email-first support, internal IT requests, and small-to-mid teams that need structure. It supports queues, templates, tags, time tracking, and a searchable history.
People compare it to Zendesk or Freshdesk. The meaningful difference is ownership.
With self-hosting, you decide how long to retain data, how inbound mail is handled, and how integrations are wired.
This is an open-source spotlight, not a step-by-step install guide. You’ll still get the production essentials: Docker Compose layout, HTTPS reverse proxying, backups, and a repeatable update routine.
Why you’d run Zammad on a VPS instead of Zendesk
Hosted helpdesks are easy to start with. You sign up, add agents, connect email, and you’re live.
The trade-offs usually show up later. Per-seat costs rise. You get less control over mail ingestion. Retention and export options are often limited.
Self-hosting Zammad is a solid fit if you:
- Want predictable costs (a VPS + storage) instead of per-agent billing.
- Need full access to the database and attachments for compliance or long retention.
- Prefer integrating with your own SMTP, SSO, or internal tools on your network.
- Support multiple brands/domains and want tighter control over inbound routing and automations.
The downside is operational responsibility. You’ll own upgrades, backups, TLS, and mail delivery hygiene.
If that trade sounds reasonable, the rest of this post will feel familiar.
For production, pick a VPS with enough headroom for indexing and attachment growth. A good baseline is a HostMyCode VPS with NVMe storage.
If you’d rather not manage patching and security hardening yourself, managed VPS hosting is often the calmer choice for a customer-facing support desk.
What Zammad is (and the license basics you should know)
Zammad is an open-source helpdesk with a web UI, email channels (IMAP/POP3 + SMTP), knowledge base features, and automation.
Under the hood, it depends on a database, a search/index layer, and background jobs.
That’s why containers work well here. You get a repeatable stack that’s easier to move, back up, and update cleanly.
Licensing still matters in 2026 because “open source” doesn’t always mean “everything is included.” Zammad has an open-source edition and also sells paid add-ons and vendor support.
Before you deploy for a business, read Zammad’s current licensing and feature matrix in the official docs. Confirm what’s included in your edition versus what needs a commercial agreement.
Don’t assume features like advanced SSO are free in every build.
Deployment architecture that behaves well in production
A stable Zammad setup on a VPS usually comes down to three layers:
- Zammad app containers (web + background workers) managed with Docker Compose.
- Reverse proxy (Nginx or Caddy) terminating HTTPS and routing traffic.
- Backups covering the database and attachments, stored off the VPS.
Keep the reverse proxy on the host (or in a dedicated proxy container). Keep the helpdesk stack on a private Docker network.
That boundary matters. Only ports 80/443 should be public. Everything else stays internal.
If you already use Caddy for other apps, reuse it. If your standard is Nginx, stick with Nginx.
The non-negotiable is TLS. Don’t expose a helpdesk over plain HTTP, even “just temporarily.”
If you want automatic certificate management, the pattern in our guide Set Up Let’s Encrypt With Caddy for a VPS Site maps well to a Zammad reverse-proxy front end.
Resource requirements (realistic sizing for small teams)
Zammad’s performance is mostly about search. Ticket content gets indexed, attachments accumulate, and background jobs run constantly.
Under-size the box and you’ll feel it. Look for slow searches, sluggish page loads, and delayed mail processing.
For a small team (1–10 agents) with typical email volume:
- CPU: 2 vCPU minimum. 4 vCPU if you expect heavy indexing or multiple channels.
- RAM: 4 GB minimum. 8 GB is safer if you keep long history or run other services.
- Disk: NVMe recommended. Plan storage for attachments (often the real growth driver).
- Swap: A small swap file can prevent OOM kills, but don’t use swap as a crutch.
One practical rule: if your public website/app shares the same VPS, put the helpdesk elsewhere.
Support tooling should stay responsive even when your app hits a traffic spike.
Compose-first install: what your stack typically looks like
Zammad is commonly deployed via Docker Compose using vendor-maintained images and a reference Compose file.
Instead of pasting a giant, version-pinned file that will go stale, here’s the on-disk structure worth aiming for:
/opt/zammad/compose.yml(ordocker-compose.yml)/opt/zammad/.envfor secrets and hostnames/opt/zammad/volumes/for persistent data (attachments, config)
Your Compose file will typically define services for:
- zammad (web app)
- zammad-scheduler and zammad-websocket (background duties)
- PostgreSQL (recommended for production deployments)
- Elasticsearch/OpenSearch (search index; required for good UX)
Two guardrails keep most people out of trouble:
- Keep the database and search services on the same Docker network as the app, and don’t expose them to the public internet.
- Use persistent volumes for the database, attachments, and any app storage that matters. Containers are disposable; volumes aren’t.
If you’ve self-hosted other apps with Compose, the pattern will look familiar.
The principles in Self-Host listmonk on a VPS With HTTPS and SMTP (separating app, database, TLS proxy, and backups) carry over cleanly.
Reverse proxy with HTTPS (Nginx example)
Put Zammad behind a reverse proxy that terminates TLS and forwards traffic to an internal container port.
Nginx is a common choice on Ubuntu, Debian, AlmaLinux, and Rocky Linux.
Assume:
- Your domain is
support.example.com - Your Zammad web container listens on
127.0.0.1:8080(or a Docker network name if proxy runs in Docker) - Certbot manages Let’s Encrypt certificates
A minimal Nginx server block (path: /etc/nginx/sites-available/zammad) looks like this:
server {
listen 80;
server_name support.example.com;
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
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;
# Basic hardening
add_header X-Frame-Options SAMEORIGIN always;
add_header X-Content-Type-Options nosniff always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
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;
}
}
Reload Nginx with:
sudo nginx -t && sudo systemctl reload nginx
If you see a proxy error during first boot (common while containers warm up), follow the troubleshooting flow in Nginx 502 Bad Gateway Fix on Ubuntu VPS.
With helpdesk stacks, the cause is often “app not ready yet,” not a permanent misconfiguration.
Mail flow: the part people underestimate
Zammad is a ticket system, but for most teams it’s really an email system with a UI.
Plan mail in three parts and the rollout goes smoother:
- Inbound: Connect a mailbox via IMAP/POP3, or route mail into a dedicated inbox per brand/department.
- Outbound: Send via SMTP with correct SPF/DKIM/DMARC alignment to avoid spam folders.
- Identity: Set a clear “From:” policy so replies come from the right address and threads stay intact.
If you already run your own SMTP, validate DNS before you onboard the helpdesk.
The checklist in Set Up DKIM, SPF, And DMARC For A Domain helps prevent a common failure mode. Tickets send successfully, but customers never see them.
If you don’t want the overhead of running mail servers, you can still self-host Zammad and use a trusted outbound SMTP provider.
Zammad doesn’t require you to host email. It just needs reliable IMAP/SMTP connectivity.
Backups: what to capture (and what people forget)
A Zammad backup isn’t just a database dump. You need a consistent set of three things:
- Database (typically PostgreSQL): tickets, users, settings, history
- Attachments / storage volume: files uploaded or attached from email
- Configuration: Compose files, environment variables, and any custom Nginx/Caddy config
On a VPS, a sensible baseline is nightly automated backups plus an offsite copy.
If the VPS disappears, you should be able to rebuild and restore in under an hour.
A practical approach that fits Docker deployments:
- Dump PostgreSQL with
pg_dumpfrom a scheduled job (cron or systemd timer). - Archive persistent volumes with
tar(orrestic/borgif you want dedupe + encryption). - Upload to object storage or a second VPS using
rcloneorrsyncover SSH.
Example backup skeleton (run on the host), assuming your database container is named zammad-db:
# Create a dated backup directory
BACKUP_DIR=/var/backups/zammad/$(date +%F)
mkdir -p "$BACKUP_DIR"
# Database dump
docker exec -t zammad-db pg_dump -U postgres -Fc postgres > "$BACKUP_DIR/zammad-postgres.dump"
# Volumes archive (adjust paths to your setup)
tar -C /opt/zammad -czf "$BACKUP_DIR/zammad-volumes.tar.gz" volumes
# Keep a copy of Compose + env (protect .env permissions)
cp /opt/zammad/compose.yml "$BACKUP_DIR/"
cp /opt/zammad/.env "$BACKUP_DIR/"
Two easy mistakes to avoid:
- Backing up mid-write with filesystem snapshots only. Use
pg_dump(logical) or proper database snapshot techniques. - Keeping backups on the same VPS. That’s not a backup; it’s a second copy in the same failure domain.
Safe upgrades: how to avoid a bad afternoon
Helpdesks are “always on.” Customers will email you whether you’re updating or not.
A safe upgrade routine stays boring on purpose:
- Read release notes for breaking changes in your target version.
- Take backups (database + volumes) and confirm you can access them.
- Pull images and restart with Compose.
- Watch logs for migrations/index rebuilds and confirm mail processing resumes.
Concrete commands (from /opt/zammad) usually look like:
docker compose pull
docker compose up -d
docker compose logs -f --tail=200
If your reverse proxy runs on the host, keep it unchanged during app upgrades.
Try not to modify Nginx/Caddy and Zammad in the same deployment unless you have a clear reason.
Unattended security updates for the OS can help, but don’t allow surprise reboots.
For a controlled setup, follow Set Up Automated Security Updates on Ubuntu VPS and schedule reboots on your terms.
Hardening checklist for a public-facing helpdesk
Zammad is an internet-facing app. Treat it the same way you’d treat a production WordPress site or a customer API.
- Firewall: allow only 22/tcp (or your SSH port), 80/tcp, 443/tcp. Block everything else.
- SSH: disable password auth, use keys, and restrict administrative access where possible.
- Backups: encrypt offsite backups; protect encryption keys.
- Updates: patch the OS regularly; update Docker images in a controlled cadence.
- Rate limiting: add basic limits on login endpoints at the proxy level if you see abuse.
If you want a quick firewall baseline on Ubuntu, Set Up UFW Firewall on Ubuntu for a Web Server gets you to a sane default in minutes.
Operational notes: logs, storage growth, and monitoring
After the first week, the problems you’ll actually see are pretty consistent:
- Disk growth: attachments and long retention. Set mailbox policies and consider attachment size limits.
- Index performance: search layer CPU/RAM usage during heavy ingestion.
- Mail delivery failures: DNS records, SMTP auth errors, or provider throttling.
Don’t run it blind. Even basic monitoring helps you catch “support feels slow” before it turns into a real outage.
For a live view of CPU, RAM, disk, and network, Netdata on a VPS is a quick win and fits well with helpdesk workloads.
Where HostMyCode fits (and what to host Zammad on)
A helpdesk is infrastructure, not a side project. It needs steady CPU, consistent storage performance, and predictable networking.
Shared hosting usually isn’t a good match. You’ll want Docker, background workers, and control over TLS and mail routing.
For most teams, a VPS hits the sweet spot: isolated resources and full root access, without dedicated-server overhead.
If you’re planning multiple internal tools (helpdesk + monitoring + wiki), size up early. Don’t run everything on the edge.
If you’re ready to put a helpdesk on infrastructure you control, start with a HostMyCode VPS sized for your mail volume and attachment growth. Prefer fewer operational tasks? Choose managed VPS hosting so updates, security baselines, and stability checks don’t get pushed to “later.”
FAQ: running Zammad in production
Do I need a dedicated server to run Zammad?
No. Many small teams run Zammad comfortably on a VPS. Choose a dedicated server only if you have high volume, strict isolation needs, or you’re consolidating many services.
Can I use Caddy instead of Nginx for TLS?
Yes. Caddy is a good fit if you want automatic HTTPS with minimal configuration. The key requirement is stable reverse proxying and correct forwarded headers.
What should I back up first if I’m short on time?
Back up the database and the attachments volume. Without those two, you don’t have tickets. Then back up your Compose files and environment variables.
How do I avoid breaking things during upgrades?
Upgrade in a maintenance window, take verified backups, and watch logs during migrations. Don’t change proxy config and Zammad versions in the same deployment unless necessary.
Should I run Zammad on the same VPS as my main website?
If your website traffic is unpredictable, keep the helpdesk separate. Support tooling needs consistent performance even during marketing campaigns or incidents.
Summary: a calmer way to run support
If you’ve outgrown a shared inbox but don’t want per-agent pricing, self-hosting Zammad is a practical middle ground.
You get real ticket workflows, full data ownership, and the ability to fit it into your existing mail and DNS setup.
To run Zammad on a VPS responsibly, keep it simple: Docker Compose, HTTPS at the edge, offsite backups, and a repeatable upgrade routine.
When you’re ready to deploy, a properly sized HostMyCode VPS gives you the control Zammad expects, without the hassle of managing a whole fleet.