After trying out many different CMS and blogging solutions, I decided to stick with ghost. Ghost's WYSIWYG editor is the best on the market in my opinion. Deploying a ghost instance is pretty straightforward as well. Since I use containers for almost everything, I started with a simple docker-compose file:
version: '3.1' services: ghost: image: ghost restart: always ports: - 2368:2368 environment: database__client: mysql database__connection__host: db database__connection__user: root database__connection__password: example database__connection__database: ghost url: http://localhost:2368 db: image: mysql:5.7 restart: always environment: MYSQL_ROOT_PASSWORD: example
That allows to deploy a ghost instance in seconds:
After this successful test I decided to deploy ghost directly to my k8s cluster. The deployment itself is straightforward, I basically just changed the "url" environment variable to match my URL:
apiVersion: apps/v1 kind: Deployment metadata: namespace: ghost name: ghost labels: app: ghost spec: [...] template: [...] spec: containers: - name: ghost image: ghost ports: - containerPort: 2368 env: [...] - name: url value: https://blog.mrupp.eu [...]
I expected this to work just fine but the result was pretty unsatisfying:
It turned out that ghost tried to redirect me to https://blog.mrupp.eu
which is exactly the URL that I entered in my web browser. The problem is that the ingress controller (in this case traefik) access the ghost service via http - ghost expects https.
The fix is to write a traefik middleware that adds a X-Forwarded-Proto header that tells ghost that the site was originally accessed via https:
apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: proto-forward namespace: ghost spec: headers: customRequestHeaders: X-Forwarded-Proto: "https" --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ghost-ingress namespace: ghost annotations: traefik.ingress.kubernetes.io/router.middlewares: ghost-proto-forward@kubernetescrd spec: rules: - host: blog.mrupp.eu http: paths: - path: / pathType: Prefix backend: service: name: ghost-service port: number: 80
Personally I think that the absolute URL configuration is a bad design choice. It not only causes errors like the above one, it also makes it very hard to deploy one ghost instance for multiple domains.