Self-Hosting a WordPress Stack with Coolify
#wordpress
#coolify
#self-hosting
#docker
#devops
Self-hosting WordPress gives you full control over performance, security, and costs. Coolify makes it much simpler by providing a PaaS-like dashboard on top of Docker, letting you deploy and manage applications, databases, networking, and TLS with minimal ops toil.
This guide walks you through deploying a production-ready WordPress stack on a single VPS using Coolify, including database, persistent storage, HTTPS, backups, and performance tuning.
What You Will Build
- WordPress running in Docker, managed by Coolify
- A MySQL or MariaDB database with persistent storage
- Optional Redis for object caching
- Automatic HTTPS via reverse proxy (Traefik)
- Domain routing, environment variables, and logs
- Backup options and an update workflow
Prerequisites
- A VPS (2 vCPU, 4 GB RAM minimum recommended; 4 vCPU, 8 GB RAM for busy sites)
- A domain and ability to create DNS records
- Ports 80 and 443 open to the internet, and 22 for SSH
- Ubuntu 22.04+ or Debian 12 commonly used
- A non-root user with sudo and SSH key access
Optional but recommended:
- A transactional email provider (e.g., Postmark, Mailgun) for WordPress emails
- An S3-compatible bucket for backups (e.g., Backblaze B2, Wasabi)
Baseline Server Setup
- Create a non-root user and harden SSH (key-based auth, disable root login).
- Enable a firewall:
- UFW: allow 22, 80, 443; deny others.
- Keep the system updated:
- Debian/Ubuntu:
sudo apt update && sudo apt upgrade -y
- Debian/Ubuntu:
- Install Docker if not already installed (Coolify can handle it during setup).
Install Coolify
Coolify provides a one-liner installer that sets up the platform and its reverse proxy. Review scripts before running in production.
Example:
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
After installation:
- The Coolify dashboard typically runs on port 8000. Access it at:
- http://YOUR_SERVER_IP:8000
- Create the admin account and finish the initial wizard.
- You can later attach a domain to the Coolify dashboard itself if desired.
Tip: Coolify uses Docker under the hood and a reverse proxy (Traefik) to manage TLS automatically via Let’s Encrypt.
Create or Connect Your Environment
For a single VPS deployment:
- In Coolify, use the “Local Docker” environment (the default on the server where Coolify is installed).
- Keep the default internal network unless you have special isolation requirements.
Provision the Database
- In Coolify, add a new Service -> Database -> choose MySQL 8 or MariaDB.
- Configure:
- Persistent volume:
- MySQL: /var/lib/mysql
- MariaDB: /var/lib/mysql
- Set root password and create an application user and database (or plan to create them later).
- Keep this database internal (do not expose a public port). WordPress will connect over the internal Docker network.
- Persistent volume:
- Deploy the database service and wait until it’s healthy.
Record the connection details you’ll use in WordPress:
- Host: the service name in Coolify (e.g.,
mysql:3306) - User, Password, Database name
Add Redis (Optional but Recommended)
- Add a new Service -> Cache -> Redis.
- Persistent volume: /data
- Keep it internal and deploy.
- You will later enable a WordPress plugin for Redis object caching and point it at the Redis host (e.g.,
redis:6379).
Deploy WordPress
Coolify often includes a one-click WordPress template. If not, add a new Application and use the official Docker image:
- Image:
wordpress:6-php8.2-apache(or a pinned version you prefer) - Internal port: 80
- Persistent volume:
/var/www/html
Environment variables (adjust names for your DB):
- WORDPRESS_DB_HOST: mysql:3306
- WORDPRESS_DB_USER: app_user
- WORDPRESS_DB_PASSWORD: strongpassword
- WORDPRESS_DB_NAME: app_db
Security and quality-of-life variables:
- WORDPRESS_CONFIG_EXTRA: use this to append PHP constants to wp-config.php. Example:
define('FORCE_SSL_ADMIN', true); define('DISALLOW_FILE_EDIT', true); define('WP_MEMORY_LIMIT', '256M'); define('WP_MAX_MEMORY_LIMIT', '512M');
If you intend to use Redis:
- Add:
WP_REDIS_HOST=redis - After WordPress is up, install and enable a Redis object cache plugin.
Configure the Domain and HTTPS
- Create a DNS A record for your site (e.g.,
www.example.com) pointing to your server IP. - In the WordPress application settings in Coolify:
- Set the domain to
www.example.com. - Enable HTTPS/auto TLS. Ensure your ACME email is configured in Coolify’s proxy settings.
- Set the domain to
- Redeploy the application if required. Traefik will obtain and renew a Let’s Encrypt certificate automatically.
Once HTTPS is active, set WordPress Address and Site Address (in Settings -> General) to the final HTTPS URL.
SMTP for Outbound Email
WordPress needs SMTP for reliable email delivery. Use a plugin such as WP Mail SMTP and add credentials from your email provider. Alternatively, you can define constants via WORDPRESS_CONFIG_EXTRA, but plugins are usually simpler.
Backups
You need both database and media backups.
Approaches:
- Database dumps: schedule
mysqldumpinside a small sidecar or via a cron job on the host, then upload to S3 with a tool like rclone or restic. - Volume snapshots: use restic to back up the WordPress
/var/www/htmlvolume and database volume to S3-compatible storage. - Offsite is critical. Store at least 7–30 days of daily backups. Test restore on a separate environment.
Example database dump script (run via cron on the host or a maintenance container):
mysqldump -h mysql -u app_user -p'SECRET' app_db \
| gzip > /backups/app_db-$(date +%F).sql.gz
Updates and Maintenance
- Pin image tags (e.g.,
wordpress:6.6.2-php8.2-apache) for predictability. Avoidlatestin production. - To update WordPress core and PHP runtime, change the image tag and redeploy, then run WordPress updates inside the admin.
- Update plugins and themes regularly. Remove unused ones.
- Monitor logs in Coolify:
- Application logs for PHP/Apache
- Database logs for slow queries
- Resource monitoring: watch CPU, RAM, and disk I/O. Scale the VPS or add caching/CDN as traffic grows.
Performance Tips
- Enable a page cache plugin (e.g., a lightweight full-page cache). Consider a CDN for static assets.
- Enable Redis object cache for database offload.
- Use optimized images and lazy loading.
- Consider moving media to object storage with a plugin that supports S3-compatible providers.
- Set appropriate PHP memory limits and opcache defaults via WORDPRESS_CONFIG_EXTRA.
Security Checklist
- Force HTTPS and set HSTS at the proxy level if appropriate.
- Set
DISALLOW_FILE_EDITtrue to disable theme/plugin editor. - Keep WordPress, themes, plugins updated.
- Use strong, unique passwords and a login rate limiter or WAF.
- Limit admin accounts; use least privilege.
- Regular backups and tested restore procedures.
Troubleshooting
- 502/Bad Gateway:
- Check if the WordPress container is healthy and listening on port 80.
- Verify domain points to the server and that the app has the correct domain in Coolify.
- Database connection errors:
- Confirm service name and port (e.g.,
mysql:3306). - Validate credentials and that the DB is ready.
- Confirm service name and port (e.g.,
- SSL issues:
- Ensure DNS has propagated and port 80 is open for HTTP-01 challenges.
- Permission errors on uploads:
- Ensure the
/var/www/htmlvolume is writable by the container’s web user.
- Ensure the
- Memory exhaustion:
- Increase PHP memory limit; add swap; upgrade VPS resources.
Going Further
- Staging environment: clone your stack in Coolify with a different domain and database to test updates safely.
- GitOps: containerize a theme or plugin development workflow and auto-deploy via Coolify.
- Multi-site: the official WordPress image supports multisite with extra configuration; ensure domain mapping and wildcard DNS as needed.
With Coolify handling orchestration, networking, and TLS, you can self-host WordPress with a clear, repeatable workflow and a clean path to scaling as your site grows.