Deploying Ghost with Kubernetes
2 min read

Deploying Ghost with Kubernetes

Deploying Ghost with Kubernetes
Photo by Dawn McDonald / Unsplash

Notes

  • Only MySQL 8 is supported as a backend for Ghost in production.
  • Ghost is a bit finnicky when there's more than one replica. I take it down to 1 replica when writing.

Full configuration

---
apiVersion: v1
kind: Namespace
metadata:
  name: homepage-tiuxo
---
---
apiVersion: v1
kind: Secret
metadata:
  name: mysql-secret
  namespace: homepage-tiuxo
type: Opaque
data:
  password: base64 encoded password
---
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
  namespace: homepage-tiuxo
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: longhorn
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ghost-pvc
  namespace: homepage-tiuxo
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: longhorn
  resources:
    requests:
      storage: 2Gi
---
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  namespace: homepage-tiuxo
  labels:
    app: ghost
spec:
  selector:
    matchLabels:
      app: ghost
      tier: database
  template:
    metadata:
      labels:
        app: ghost
        tier: database
    spec:
      containers:
      - image: mysql:8
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        - name: MYSQL_USER
          value: ghost
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password       
        ports:
          - containerPort: 3306
        volumeMounts:
          - name: mysql-vol
            mountPath: /var/lib/mysql
      volumes:
        - name: mysql-vol
          persistentVolumeClaim:
            claimName: mysql-pvc
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ghost
  namespace: homepage-tiuxo
  labels:
    app: ghost
spec:
  replicas: 3
  selector:
    matchLabels:
      app: ghost
      tier: frontend
  template:
    metadata:
      labels:
        app: ghost
        tier: frontend
    spec:
      volumes:
        - name: ghost-vol
          persistentVolumeClaim:
            claimName: ghost-pvc
      containers:
        - image: ghost
          name: ghost
          env:
            - name: url
              value: https://tiuxo.com
            - name: database__client
              value: mysql
            - name: database__connection__host
              value: ghost-database
            - name: database__connection__user
              value: root
            - name: database__connection__password
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: password
            - name: database__connection__database
              value: ghost
          ports:
            - containerPort: 2368
          volumeMounts:
            - mountPath: "/var/lib/ghost/content"
              name: ghost-vol
---
---
apiVersion: v1
kind: Service
metadata:
  name: ghost-database
  namespace: homepage-tiuxo
spec:
  ports:
    - name: mysql
      protocol: TCP
      port: 3306
  selector:
    app: ghost
    tier: database
  clusterIP: None
---
apiVersion: v1
kind: Service
metadata:
  name: ghost-frontend
  namespace: homepage-tiuxo
spec:
  ports:
    - name: http
      protocol: TCP
      port: 2368
  selector:
    app: ghost
    tier: frontend
---
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: homepage-tiuxo-ingress
  namespace: homepage-tiuxo
  annotations:
    kubernetes.io/ingress.class: traefik
    ingress.kubernetes.io/ssl-redirect: "true"
    traefik.backend.loadbalancer.stickiness: "true"
    cert-manager.io/cluster-issuer: buypass
spec:
  tls:
    - hosts:
      - tiuxo.com
      - www.tiuxo.com
      secretName: homepage-tiuxo-tls
  rules:
    - host: tiuxo.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: ghost-frontend
                port:
                  number: 2368