3 min read

How to Connect Ghost to a Managed MySQL Database on DigitalOcean with Helm

How to Connect Ghost to a Managed MySQL Database on DigitalOcean with Helm
Photo by Growtika / Unsplash

So, you installed Ghost on your Kubernetes cluster with the bitnami/ghost Helm chart.

That's pretty cool, congrats! 🥳

However, now you have a MySQL pod for each Ghost instance in your cluster that you have to manage yourself.

That's not bad at all but sometimes, it's nice with simplicity and that's where DigitalOcean's managed MySQL service comes in handy!

I've made a list of pros and cons of managed vs. unmanaged MySQL servers here.

Worry-Free Managed MySQL Hosting | DigitalOcean
Leave the complexity of MySQL administration to us. We’ll handle setting up, backing up, and updating — so you can focus on building great apps.

Check out their managed MySQL service here

Setting up an external database

Using an external database with Ghost installed with Helm is pretty simple but requires some changes to your Helm values.yaml file.

Ensure Helm doesn't start a MySQL instance

When installing Ghost with Helm, it provisions a MySQL pod by default.

In this case, we want to use an external database, so we need to disable the MySQL pod in values.yaml.

mysql:
  enabled: false

Disable provisioning of the MySQL pod

Configure Ghost to use the external database

Go to the Databases section in the Control Panel, click on the database server you created and then click on VPC Network under the Connection Details section:

The connection details pane in the control panel

When using the VPC Network, you should be able to connect to the external database if your Nodes are in the same region as the database server.

Under Settings you can also add Trusted sources which can be tags, clusters, etc.

Here's the important section of your values.yaml file that you need to fill out with the details from the Connection Details section:

externalDatabase:
  # Replace with actual hostname for your instance on DigitalOcean
  host: private-db-mysql-region.db.ondigitalocean.com
  port: 25060 # port used my DigitalOcean's managed MySQL
  user: yourUsername # replace with your database username
  password: yourPassword # replace with your database password
  database: yourDatabase # replace with your database name
  ssl: true # SSL is required
  # We add this to a Kubernetes secret later
  sslCaFile: "/etc/ssl/certs/ca-certificate.crt"

Configure external database settings

Download the CA certificate from DigitalOcean

Go to the Databases section in the Control Panel, click on the database server you created and click on Download CA certificate which should be right under the Connection Details section:

The connection details pane where you can download the CA certificate

Add the CA certificate to your Kubernetes cluster

When you've setup your managed MySQL database on DigitalOcean, you can download the CA certificate from the Control Panel.

This certificate is needed in order to create a secure SSL connection to the external database.

In order to make this certificate available in the Ghost pod, we can store the CA certificate in a secret on the Kubernetes cluster by running the following command in the directory where you put the downloaded CA certificate from the Control Panel:

kubectl create secret generic mysql-ca-cert --from-file=ca-certificate.crt

Create a secret called "mysql-ca-cert" from the local file "ca-certificate.crt".

Now we just need to mount it, so it's accessible in the pod and container with the following section in our values.yaml file:

extraVolumes:
  - name: "mysql-ca-cert"
    secret:
      secretName: "mysql-ca-cert"

extraVolumeMounts:
  - name: "mysql-ca-cert"
    mountPath: "/etc/ssl/certs"
    readOnly: true

Add the volume to the pod and mount the certificate in the container

That's all, folks! 🎉

Now you can celebrate with a cup of coffee. ☕
Then install or upgrade using Helm.

helm install your-ghost bitnami/ghost -f values.yaml

Install with Helm

export GHOST_PASSWORD=$(kubectl get secret --namespace "default" your-ghost -o jsonpath="{.data.ghost-password}" | base64 -d)
helm upgrade your-ghost bitnami/ghost --reuse-values --set ghostPassword=$GHOST_PASSWORD -f values.yaml

Upgrade existing instance with Helm