How to Install Sendy on Docker: Complete Guide
Before you start
Running Sendy in Docker is possible as a packaging strategy, but it is not the same as running a stateless web application. Sendy needs its configuration, uploads and database to survive container recreation, and its scheduled PHP scripts need a reliable scheduler. Docker is therefore best for operators who already understand persistent volumes, backups and container networking.
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 server with Docker Engine and Compose.
- Sendy license/package.
- Persistent volume for Sendy files/uploads.
- Persistent MySQL volume.
- Reverse proxy with HTTPS.
- Cron/scheduler.
- Amazon SES account and verified identities.
Architecture
Internet → reverse proxy → PHP/web container → persistent Sendy files → 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. Define persistent storage
Create one persistent volume for MySQL and another for Sendy's application data/uploads. Never keep subscriber data or uploaded assets only inside a disposable container layer.
2. Build the PHP image
Use a supported PHP image and install the extensions required by the current Sendy release. Pin the base image rather than using an unbounded latest tag in production.
3. Create the MySQL service
Use MySQL/MariaDB with a persistent data volume. Put credentials in environment files or secrets that are protected from source control.
4. Add the web layer
Use Apache or Nginx inside the stack, or put Caddy/Nginx in front of the PHP service. Only expose the reverse proxy publicly.
5. Populate Sendy
Copy the licensed Sendy package into the persistent application volume. Configure includes/config.php and make uploads writable by the PHP process.
6. Start the stack
Bring up the database first, wait until it accepts connections, then start the web/PHP service. Container startup order is not the same thing as database readiness.
7. Run the installer
Open the HTTPS hostname and complete the Sendy installer. Verify the application can write to uploads and the database connection works.
8. Configure cron
Use host cron or a dedicated scheduler container to execute scheduled.php and autoresponders.php. Run the command inside the PHP container and verify it succeeds before scheduling it.
9. Configure SES
Enter the correct AWS region and credentials, verify identities and ensure the SES account has production access. Docker does not change any SES requirements.
10. Back up and upgrade safely
Back up the MySQL volume and Sendy application/uploads. When upgrading, follow Sendy's current update instructions and test on a staging copy first.
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
Uploads disappear
The uploads directory is not persistent. Mount it from a named volume or host path.
Database resets
The MySQL data directory was not mounted persistently.
Cron cannot find PHP
Execute the command inside the PHP container or use the correct host/container path; do not mix host paths with container paths.
Proxy returns 502
Check service names, exposed ports and PHP-FPM/Apache health.
Upgrade loses changes
Follow the vendor's current update procedure and preserve config/uploads separately.
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?
Docker is useful when you want reproducibility and isolation, but Sendy is a small PHP application and a traditional VPS can be simpler. Choose Docker when you already operate containers and have a clear backup/upgrade strategy. Do not choose it simply because containers sound more modern.
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 Caddy
- 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
- Docker official Compose documentation