Skip to main content

Overview

Ghost is the open-source publishing platform for professional blogs, newsletters, and paid memberships, with a first-class editor and REST Content/Admin APIs. This template deploys a single stateful Ghost workload backed by a bundled MySQL 8 database, with durable content storage, an HTTPS public site, optional SMTP email, and optional scheduled database backups to object storage.

Architecture

  • Ghost — Stateful, single-replica workload serving the site, editor, and Content/Admin APIs on port 2368. Boots through a startup script that sets the public url from the canonical endpoint.
  • MySQL 8 — Backing database provisioned from the mysql template as a subchart (image pinned to mysql:8 — the only database Ghost supports) and connected to Ghost automatically.

What Gets Created

  • Stateful Ghost Workload — The Ghost server with configurable CPU and memory.
  • Stateful MySQL Workload — Single-replica MySQL 8, automatically connected to Ghost.
  • Volume Sets — A persistent volume set for Ghost content (/var/lib/ghost/content: uploaded images, themes, logs, adapters) and one for MySQL data.
  • Secrets — An opaque secret holding the startup script and the MySQL credentials secret.
  • Identity & Policy — An identity bound to the Ghost workload with reveal access scoped to exactly the secrets it mounts (plus your SMTP secret when mail is enabled).
  • Cron Backup Workload (optional) — Scheduled MySQL dumps to object storage, created only when mysql.backup.enabled is true.
This template does not create a GVC. You must deploy it into an existing GVC.

Prerequisites

None for a default install — it deploys with a working MySQL 8 backend and an auto-assigned HTTPS endpoint. Two optional features need setup before installing:
  • SMTP email — for member sign-in links and newsletters, create a dictionary secret with keys user and password first (see Mail).
  • Database backups — an AWS S3 or GCS bucket plus a Control Plane Cloud Account (see Backing Up).
Install using your preferred method:

UI

Browse, install, and manage templates visually

CLI

Manage templates from your terminal

Terraform

Declare templates in your Terraform configurations

Pulumi

Declare templates in your Pulumi programs

Configuration

Key configuration values (see the template’s values.yaml for the complete set):

Ghost Application

  • image — The official Ghost image from Docker Hub (library/ghost, Alpine variant).
  • resources — CPU and memory bounds for the Ghost workload.
  • volumeset.capacity — Initial content volume size in GiB (minimum 10). Holds uploaded images, themes, logs, and adapters at /var/lib/ghost/content.

Site URL

  • publicUrl — The public URL Ghost uses to build page links and email links. Leave empty (default) to auto-derive the canonical *.cpln.app endpoint at boot. Set it to your custom domain (e.g. https://blog.example.com) once you attach one, so links and emails point at the right host.

Mail (SMTP)

Email powers member sign-in links, staff invitations, and newsletters. It is off by default — the entire mail configuration is gated on mail.secretName being non-empty. To enable it, create a dictionary secret with your SMTP credentials before installing:
Then set:
  • mail.secretName — The name of the dictionary secret (keys user and password). The template grants the Ghost identity reveal on exactly this secret.
  • mail.host — Your SMTP server hostname (e.g. smtp.mailgun.org).
  • mail.port / mail.secure587 with secure: false for STARTTLS (default), or 465 with secure: true for SSL.
  • mail.from — The From address for outgoing mail (e.g. "Ghost <noreply@example.com>").

Access

  • publicAccess.enabled — Serve the site and admin over HTTPS on the auto-assigned *.cpln.app canonical endpoint (default). Set to false for an internal-only instance — Ghost then derives its URL from the internal DNS name.
  • internalAccess.type — Controls which workloads can reach Ghost over the internal network:

Backing Database

  • mysql.image — Pinned to mysql:8. Ghost supports only MySQL 8 — not MySQL 9 and not MariaDB. Do not change this.
  • mysql.config.db / user / password / rootPassword — Credentials for the bundled MySQL, applied on first startup. Change both passwords before installing.
  • mysql.resources / mysql.volumeset.capacity — CPU/memory bounds and initial volume size for the MySQL workload.
  • mysql.internalAccess.type — Controls which workloads can reach MySQL directly.
  • mysql.enablePhpMyAdmin — Off by default to keep the footprint to Ghost plus its database.
MySQL credentials are only applied on first startup when the data directory is empty. Changing them in values after the initial deployment has no effect on the running database. To fully reset, helm uninstall (which deletes the volume sets) and reinstall.

Connecting

After deploy, open https://<canonical>.cpln.app/ghost in a browser to create the owner account, then start publishing. Until the owner exists, the site serves the default theme with no admin user.

Backing Up

Database backups are optional and disabled by default. When enabled, a cron workload runs a scheduled mysqldump of the Ghost database and uploads it (gzipped) to your bucket under the configured prefix. Enable with mysql.backup.enabled: true, pick a mysql.backup.provider, and complete the storage setup below before installing.
1

Create a bucket

Create an S3 bucket. Set mysql.backup.aws.bucket and mysql.backup.aws.region to match.
2

Set up a Cloud Account

If you do not have one, create a Cloud Account for your AWS account. Set mysql.backup.aws.cloudAccountName to its name.
3

Create a bucket-scoped IAM policy

Create an IAM policy granting the required S3 actions on the bucket, and set mysql.backup.aws.policyName to its name:

Restoring a Backup

Backups are standard gzipped mysqldump archives named mysql-<timestamp>.sql.gz. To restore, download the archive from your bucket and load it into a MySQL 8 instance:
The dump recreates the full ghost database — posts, members, settings, and users. Uploaded images and themes live on the Ghost content volume set, not in the database, so a database restore covers content and configuration but not media files.

Important Notes

  • Single replica by design. Ghost has no upstream clustering support, so there is no replicas knob. Durability comes from the MySQL backend, the content volume set, and optional scheduled backups. Put a CDN in front of a busy public site to absorb the brief blip during a restart or upgrade.
  • MySQL 8 only. Ghost does not support MySQL 9 or MariaDB — keep mysql.image: mysql:8.
  • Create the owner account first. After deploy, visit /ghost to run the setup wizard. Until then the site is public with the default theme and no admin exists.
  • Change both database passwords before installing. They seed the database on first boot and cannot be changed by editing values afterward — uninstalling (which deletes the volume sets) and reinstalling is the reset path.
  • SMTP is a prerequisite secret, not a value. Create the dictionary secret (keys user, password) before install and reference it via mail.secretName. Leaving it empty keeps email fully off.
  • Set publicUrl when using a custom domain so page links and emails point at the right host. Empty auto-derives the canonical *.cpln.app endpoint.
  • Content survives redeploys under the same release name — posts and settings in MySQL, media on the content volume set. Uninstalling deletes both volume sets and all data.

External References

Ghost Documentation

Official Ghost product documentation

Configuration Reference

Full reference of Ghost configuration options

Supported Databases

Why Ghost requires MySQL 8

Official Docker Image

The library/ghost image on Docker Hub

Ghost Template

View the source files, default values, and chart definition