Why self-host your blog platform
Publishing on a closed platform deprives you of control over your audience, your data and your SEO. By self-hosting Ghost or WordPress on a VPS, you own your content, your URLs, your audience data and your subscriber list. WordPress, written in PHP, offers an ecosystem of tens of thousands of themes and plugins: it's the Swiss army knife that becomes e-commerce, portfolio or showcase site. Ghost, written in Node.js, is focused: a streamlined editor, native performance, built-in membership and newsletters without a plugin, and a fast front-end by design. If you're building a feature-rich site, WordPress is the obvious choice; if you want to publish fast and monetize through subscription, Ghost shines.
The benefits of self-hosting
- Full ownership of the content, URLs and audience data, with no dependence on a platform.
- No per-subscriber fee or commission on revenue (unlike hosted offerings).
- Freedom of themes, plugins (WordPress) or customization of the Handlebars theme (Ghost).
- Control of technical SEO: URLs, sitemaps, metadata and loading performance.
- Newsletters and membership built in (Ghost) or via extensions (WordPress), with no intermediary.
- Backups and migrations under your control, with no proprietary lock-in.
| Criterion | Ghost | WordPress |
|---|---|---|
| Technology | Node.js | PHP |
| Database | MySQL 8 | MySQL / MariaDB |
| Ecosystem | Handlebars themes, API integrations | Tens of thousands of plugins and themes |
| Newsletters / membership | Native, no plugin | Via third-party extensions |
| Default performance | Very fast (lightweight front-end) | Variable, depends on plugins/cache |
| Versatility | Focused on publishing and subscription | Universal (blog, e-commerce, showcase) |
| Recommended RAM | 1 to 2 GB | 1 to 2 GB (more depending on plugins) |
| Target profile | Creators and monetized media | Any extensible web project |
Prerequisites for each platform
Ghost strictly requires MySQL 8 (not MariaDB in production) and Node.js, provided in its official Docker image. A VPS of 1 vCPU and 2 GB of RAM handles a comfortable blog. WordPress runs on 1 vCPU and 1 GB for a light site, but climbs quickly with plugins and an object cache: plan for 2 GB and Redis as soon as traffic rises. In both cases, an NVMe disk significantly speeds up rendering. You need Docker Compose v2, a dedicated domain (blog.mydomain.com), an HTTPS reverse proxy, and for WordPress attention to upload_max_filesize if you publish a lot of media.
Deploy Ghost (or WordPress) on a VPS
Declare the database
For Ghost, a mysql:8 service with a persistent volume and dedicated credentials. For WordPress, mariadb:11 or mysql:8 works. Isolate them on an internal Docker network, not publicly exposed.
Configure the application container
For Ghost, the ghost:5-alpine image with url=https://blog.mydomain.com, database__client=mysql and the connection parameters. For WordPress, the wordpress:php8.3-apache image with WORDPRESS_DB_HOST and the credentials.
Mount the content volumes
Mount /var/lib/ghost/content (Ghost) or /var/www/html/wp-content (WordPress) on a dedicated volume, to preserve themes, images and uploads during image updates.
Launch and initialize
Run docker compose up -d. Ghost listens on 2368, WordPress on 80. Go to /ghost to create the Ghost admin account, or follow the WordPress installation wizard.
Reverse proxy and HTTPS
Route blog.mydomain.com via Caddy/Traefik with an automatic Let's Encrypt certificate. Check that the configured URL is indeed in https on the application side, otherwise the resources and redirects will be in the clear.
Configure email sending and caching
Connect an SMTP service (transactional) for Ghost newsletters or WordPress emails. Enable an HTTP cache on the proxy side and, for WordPress, a Redis object cache to absorb the traffic.
With Ghost, be sure to configure transactional mail from installation: without a functional SMTP, the sending of newsletters and members' magic-link login emails fails silently, and you only discover it on the first send. Also serve images via a long cache on the reverse proxy side since the Ghost front-end is already static. For WordPress, install only maintained plugins and enable a page cache (FastCGI/Varnish) upstream: that's what makes the difference between a fast blog and a site that crawls under load.