How to Self-Host a Ticketing System
Self-hosting gives you complete control over your support data, eliminates per-agent licensing costs, and lets you customize the platform to match your workflows. The trade-off is that you accept responsibility for server maintenance, security patches, and backups. This guide assumes you have basic Linux command-line familiarity and can follow terminal instructions.
Step 1: Choose Your Server Infrastructure
The server requirements depend entirely on which help desk platform you choose. PHP-based platforms like osTicket and FreeScout are the lightest, running comfortably on a VPS with 1 GB of RAM, a single CPU core, and 20 GB of SSD storage. Zammad needs at least 4 GB of RAM, 2 CPU cores, and 40 GB of storage because it runs Elasticsearch, PostgreSQL, and Redis alongside the Ruby application.
For a PHP-based help desk, any VPS provider will work. DigitalOcean, Vultr, Linode, and Hetzner all offer suitable plans starting at $4 to $6 per month. Choose a data center location close to your team for the best agent experience. If your customers are geographically distributed, pick a central location or use a CDN for static assets.
For Zammad or Znuny, start with a 4 GB RAM plan and plan to scale up if your team grows. Docker-based deployments make it easier to move between providers later, so do not over-invest in infrastructure at the start. You can always resize the VPS when you need more capacity.
Choose Ubuntu 22.04 LTS or Debian 12 as your operating system. Both have long-term support, large package repositories, and extensive documentation. CentOS and Rocky Linux also work, but the community help resources for Ubuntu are significantly larger, which matters when you are troubleshooting issues at 2 AM.
Step 2: Install the Web Stack
For PHP-based platforms (osTicket, FreeScout, UVdesk), you need a LEMP or LAMP stack: Linux, Nginx (or Apache), MySQL (or MariaDB), and PHP. Start by updating the system packages, then install the components.
Install Nginx as your web server. It handles concurrent connections more efficiently than Apache and uses less memory, which matters on a small VPS. Install MySQL 8.0 or MariaDB 10.6+ for the database. Create a dedicated database and user for the help desk application. Never run the application as the MySQL root user.
Install PHP 8.1 or 8.2 with the extensions your chosen platform requires. Common requirements include php-mysql, php-mbstring, php-xml, php-curl, php-gd, php-imap, php-zip, and php-intl. Check the specific platform's documentation for its exact extension list. Configure PHP-FPM to run with enough worker processes for your expected traffic, starting with 5 to 10 workers for a small deployment.
For Zammad, the recommended approach is Docker Compose. Install Docker and Docker Compose on the server, then use Zammad's official docker-compose.yml file. This bundles PostgreSQL, Elasticsearch, Redis, Memcached, and the Zammad application itself. The Docker Compose setup handles inter-service networking and startup ordering, saving you from configuring each component individually.
Step 3: Secure the Server
Before installing any application, lock down the server. Configure the UFW firewall to allow only ports 22 (SSH), 80 (HTTP), and 443 (HTTPS). Block everything else. If you access the server from a fixed IP address, restrict SSH access to that IP only.
Disable password-based SSH login and require key-based authentication. Generate an SSH key pair on your local machine if you do not already have one, copy the public key to the server, then disable PasswordAuthentication in the SSH configuration. This single change eliminates the most common attack vector against Linux servers.
Disable root login over SSH. Create a regular user account with sudo privileges and use that for all server management. Install and configure fail2ban to automatically block IP addresses that make repeated failed login attempts. Set it to ban after 5 failures for 30 minutes.
Install SSL certificates using Certbot and Let's Encrypt. Run Certbot with the Nginx plugin, which automatically configures HTTPS and sets up certificate auto-renewal. Verify that the renewal cron job is active by checking the systemd timer or crontab. An expired SSL certificate will display security warnings to every customer who visits your support portal.
Enable automatic security updates for the operating system. On Ubuntu, the unattended-upgrades package handles this. Configure it to install security patches automatically but leave non-security updates for manual review. This ensures critical vulnerabilities are patched promptly without risking stability from untested feature updates.
Step 4: Install the Help Desk Application
Download the latest stable release from the project's official website or GitHub repository. Do not use development branches for production. Extract the files to your web root directory, typically /var/www/helpdesk or similar.
Set file ownership to the web server user (www-data on Ubuntu/Debian) and configure directory permissions. The application needs write access to upload directories, cache directories, and log files. A common pattern is to set directories to 755 and files to 644, with the upload and cache directories set to 775 so the web server can write to them.
Configure your Nginx server block to point to the application's public directory. Set the document root, configure PHP-FPM processing for .php files, and add URL rewrite rules if the application requires them. Most platforms provide example Nginx configurations in their documentation.
Open your browser and navigate to the installation URL. Most platforms provide a web-based installer that checks system requirements, creates database tables, and sets up the initial administrator account. Follow the installer prompts, entering the database credentials you created in step 2. Save the admin credentials in a password manager immediately after creation.
After installation, remove or restrict access to the installer directory. Leaving it accessible is a security risk because anyone who discovers it could potentially reinstall the application or access configuration details.
Step 5: Configure Email Piping
Email integration is what transforms a ticketing system from a manual tool into an automated one. Your support email address needs to connect to the help desk so that incoming messages automatically create tickets and outgoing responses send through your mail system.
For inbound email, most platforms support two methods: IMAP polling and direct piping. IMAP polling is simpler to configure. You enter the IMAP server address, port, username, and password in the help desk admin panel, and the application checks the mailbox on a schedule (typically every 2 to 5 minutes via a cron job). Direct piping is faster because the mail server forwards messages to the application immediately, but it requires access to the mail server configuration, which is not available on all hosting setups.
For outbound email, configure SMTP with a transactional email service like Amazon SES, Postmark, Mailgun, or SendGrid. Sending email directly from your VPS works technically, but deliverability will be poor. Transactional email services handle SPF, DKIM, and DMARC authentication, manage IP reputation, and process bounces properly. Amazon SES costs about $0.10 per 1,000 emails, which is negligible for most support volumes.
Set up the DKIM, SPF, and DMARC DNS records that your email service requires. These records authenticate your outbound email and prevent it from landing in spam folders. Test your configuration by sending a ticket reply to a Gmail address and checking the message headers for "PASS" results on SPF and DKIM authentication.
Configure the help desk to use your support address as the From address on outgoing emails. Set up auto-responders to acknowledge ticket creation, and customize the email templates to match your brand. Test the full round trip: send an email to support@yourdomain.com, verify that a ticket is created, reply from the agent interface, and confirm that the customer receives the reply.
Step 6: Set Up Backups and Monitoring
Your help desk contains customer data, conversation history, and operational records that you cannot afford to lose. Automated backups are non-negotiable for any self-hosted production system.
Set up a daily database backup using mysqldump (for MySQL/MariaDB) or pg_dump (for PostgreSQL). Compress the output and copy it to off-site storage, whether that is an S3 bucket, a Backblaze B2 bucket, or a separate server. Retain at least 30 days of daily backups and 12 months of monthly backups. Test your restore process at least once before you need it in an emergency.
Back up the application files separately. While you can always re-download the application code, uploaded attachments, custom templates, and configuration files are unique to your installation. Use rsync to copy the relevant directories to your off-site storage on the same schedule as your database backups.
Set up uptime monitoring with a service like UptimeRobot, Hetrix Tools, or Better Uptime. Configure it to check your help desk URL every 1 to 5 minutes and alert you via email, SMS, or Slack when the site goes down. Also monitor disk space usage. Help desk databases grow continuously, and a full disk will crash the application. Set an alert for 80% disk usage so you have time to expand storage or clean up old data before it becomes critical.
Document your disaster recovery procedure. Write down the exact steps to restore service from backups on a fresh server. Include the server provisioning commands, software installation steps, backup restore commands, DNS changes, and SSL certificate setup. Store this document outside of the server itself, somewhere you can access it even when the server is down.
Self-hosting a ticketing system is straightforward if you approach it methodically. Secure the server first, install the application, connect your email, and automate your backups. The ongoing maintenance commitment is real but manageable: apply security patches promptly, verify your backups monthly, and monitor uptime continuously. The reward is full control over your support infrastructure at a fraction of the cost of SaaS alternatives.