How to Install Sendy on Caddy: Complete Guide
Before you start
Caddy can simplify the web layer of a Sendy installation because it can terminate HTTPS automatically and pass PHP requests to PHP-FPM. Sendy's own documentation is centered on standard PHP hosting rather than a Caddy-specific configuration, so the safest approach is to keep Sendy's application behavior unchanged and use Caddy only as the web server. Amazon SES and Sendy's scheduled jobs remain completely separate from Caddy.
Important: installation instructions can change between software releases. Use the version bundled with your license and compare the vendor's current requirements before copying commands into production. Where this article uses an adapted Caddy or Docker pattern, it is clearly labeled rather than presented as vendor certification.
What you need
- Linux VPS with sudo/root.
- DNS hostname pointing to the server.
- Caddy and PHP-FPM.
- MySQL/MariaDB.
- Sendy license/package.
- Amazon SES account and verified identities.
- Cron for scheduled.php and autoresponders.php.
Architecture
Domain → Caddy → PHP-FPM → Sendy → MySQL → Amazon SES
Keeping these layers separate makes troubleshooting easier. If the web dashboard works but campaigns do not send, the problem may be in cron, the queue, the delivery server or the provider rather than in the web server. Conversely, a 502 or 500 error normally belongs to the web/PHP layer.
Step-by-step installation
1. Prepare DNS and firewall
Point sendy.example.com to the VPS. Open ports 80 and 443 and keep MySQL private. Create a sudo user and patch the operating system.
2. Install PHP-FPM and MySQL
Install the PHP version and extensions supported by your Sendy release. Start PHP-FPM and create the Sendy database/user.
3. Upload Sendy
Extract the Sendy package into a directory such as /var/www/sendy. Edit includes/config.php with APP_PATH and database credentials. Make the uploads directory writable by PHP.
4. Configure Caddy
Caddy's official PHP pattern uses root, php_fastcgi and file_server. A basic site block can look like: sendy.example.com { root * /var/www/sendy; php_fastcgi unix//run/php/php8.3-fpm.sock; file_server }. Adjust the socket and PHP version to your server.
5. Check application routing
Sendy is a conventional PHP application and its supplied .htaccess/routing assumptions may differ from a generic Caddy site. Test login, install endpoints, assets and forms. If a vendor-specific rewrite is required, translate it deliberately rather than adding broad rewrites.
6. Enable automatic HTTPS
Caddy automatically provisions a public certificate when the hostname is configured and ports 80/443 are reachable. Verify DNS before starting Caddy.
7. Run Sendy installer
Open the HTTPS hostname, enter the license and admin details and complete installation.
8. Configure cron
Caddy does not run scheduled tasks. Add scheduled.php and autoresponders.php through system cron. Use the absolute PHP binary path if required.
9. Connect SES
Configure the AWS region and SES credentials in Sendy, verify the sending identity and ensure SES production access is available.
10. Test and monitor
Check Caddy logs, PHP-FPM logs, Sendy scheduled jobs and SES events. Send a test campaign before importing a large list.
Post-install configuration
Once the installer finishes, resist the temptation to immediately import a large list and launch a campaign. First configure the sending layer, domain authentication, bounce handling and unsubscribe behavior. Your application can be perfectly healthy while the email infrastructure is not ready for production.
1. Configure the sending service
Use a delivery service or MTA that is appropriate for your sending volume and compliance requirements. Record the exact SMTP/API endpoint, credentials, region and encryption settings. Never publish credentials in screenshots, tutorials, public repositories or support tickets.
2. Authenticate the sending domain
Publish the SPF, DKIM and DMARC records required by your chosen delivery service. If the provider gives you DKIM CNAME records, use those exact values. Avoid creating multiple conflicting SPF records. Start DMARC in a monitoring mode when you are still mapping legitimate senders, then tighten the policy once authentication is verified.
3. Configure bounces and complaints
A campaign system should not keep treating permanently failing addresses as healthy subscribers. Configure the application's bounce/complaint workflow and monitor the resulting logs. If your provider exposes feedback-loop events, connect them where the application supports it.
4. Test with a small list
Send a controlled test to addresses you own at more than one mailbox provider. Check authentication results, rendering, unsubscribe behavior, tracking, bounce handling and queue processing. Only after the end-to-end workflow passes should you increase campaign volume.
Common mistakes to avoid
- Installing a PHP version without checking the application's current compatibility requirements.
- Using the database root account inside the application.
- Making the entire application directory world-writable.
- Putting passwords or AWS credentials into a public repository.
- Assuming a successful login means scheduled jobs are working.
- Sending a large campaign before SPF/DKIM/DMARC and bounce handling are verified.
- Treating the application as the email delivery server when it actually relies on an external SMTP/API provider.
- Skipping backups before upgrades.
Troubleshooting
502 Bad Gateway
Check the PHP-FPM socket path and service status.
HTTPS not issued
Confirm DNS and public access to ports 80/443.
Static files missing
Check the Caddy root and file permissions.
Cron not running
Use system cron and verify the absolute PHP path.
SES works manually but not scheduled
The problem is usually the scheduled.php cron path or environment, not Caddy.
Security checklist
- Use SSH keys where possible and disable unnecessary remote access.
- Keep the operating system, PHP runtime and application patched.
- Use a dedicated database account.
- Keep MySQL private unless remote access is explicitly required.
- Use HTTPS for the administration interface.
- Protect application configuration and secret files.
- Back up the database and uploaded/application data.
- Test restoring a backup rather than assuming it is usable.
- Monitor disk, RAM, CPU, queue depth and application logs.
When should you choose this installation method?
Caddy is useful when you want automatic HTTPS and a simple web-server configuration on a VPS. It is not a replacement for Sendy's scheduler or SES. Because Caddy is an adapted deployment path, test the full Sendy workflow after every major application or PHP upgrade.
Final checklist
- ☐ DNS resolves to the server
- ☐ Supported PHP/runtime is installed
- ☐ Database and dedicated user created
- ☐ Application installer completed
- ☐ Correct file permissions applied
- ☐ HTTPS works
- ☐ Cron/worker jobs execute
- ☐ Sending service connected
- ☐ SPF/DKIM/DMARC verified
- ☐ Bounce/complaint processing tested
- ☐ Unsubscribe tested
- ☐ Backup created and restore plan documented
- ☐ Small end-to-end test campaign completed
Related installation guides
- How to Install Sendy on Ubuntu VPS
- How to Install Sendy on cPanel
- How to Install Sendy on Docker
- Browse all self-hosted email software installation guides
- About Abhishek Sharma
Sources & references
This guide uses the following vendor or platform documentation. Where a deployment method is an adaptation rather than vendor documentation, that distinction is stated in the article.
- Sendy official Get Started guide
- Sendy official update/release information
- Caddy official PHP-FPM documentation
- Caddy official HTTPS quick start