Cómo desplegar Ghost (CMS/Blog) en Kubernetes

Una solución simple para desplegar Ghost CMS en Kubernetes, probado en k3s.
GitHub - sredevopsdev/ghost-on-kubernetes: Deploy an updated, full Ghost v5.x.x (Blog CMS from @TryGhost) on any Kubernetes (k3s, GKE, AKS, etc)
Deploy an updated, full Ghost v5.x.x (Blog CMS from @TryGhost) on any Kubernetes (k3s, GKE, AKS, etc) - GitHub - sredevopsdev/ghost-on-kubernetes: Deploy an updated, full Ghost v5.x.x (Blog CMS fro…
Ghost on Kubernetes by SREDevOps
This repo deploys a clean Ghost CMS v5.xx.x from @TryGhost (upstream) in Kubernetes, as a Deployment using our custom image built based on the "official" Ghost 5 debian image, but with some modifications:
- We use the official Node 18 Hydrogen bookworm slim image as base.
- Removed gosu, we use the default user (node) to run Ghost.
- Modified the entrypoint to run as node user, so we can run the pod as non-root.
- Update every possible dependencies in the base image to minimize vulnerabilities.
- We update npm and ghost-cli to the latest versions on every build.
- We use the latest version of Ghost 5.
Note: At this time, we dropped support for arm64 and armv7l, but we will add it back soon. Pull requests are welcome.
Installation
1. Clone the repository
# Clone the repository
git clone https://github.com/sredevopsdev/ghost-on-kubernetes.git
# Change directory
cd ghost-on-kubernetes
# Checkout to your local branch (optional)
git checkout -b my-branch
2. Review the default values and make changes as per your requirements, if any into the following files
- deploy/00-namespace.yaml
- deploy/01-config.production.yaml # Check config.production.sample.json for more details
config.production.sample.json: |
{
"url": "http://localhost:2368", # Change the url as per your requirements
"admin": {
"url": "http://localhost:2368" # Change the url as per your requirements
},
"server": {
"port": 2368,
"host": "0.0.0.0"
},
"mail": {
"transport": "SMTP", # Or use Mailgun, etc.
"options": {
"service": "Google",
"host": "smtp.gmail.com",
"port": 465,
"secure": true,
"auth": {
"user": "[email protected]",
"pass": "pass"
}
}
},
"logging": {
"transports": [
"stdout"
]
},
"database": {
"client": "mysql",
"connection":
{
"host": "mysql-ghostk3s", # Same as service name
"user": "userdb", # Same as in secret
"password": "passdb", # Same as in secret
"database": "db", # Same as in secret
"port": "3306"
}
},
"debug": true,
"process": "local",
"paths": {
"contentPath": "/var/lib/ghost/content"
}
}
- deploy/01-secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysql-ghostk3s
namespace: ghostk3s
type: Opaque
stringData:
MYSQL_DATABASE: mysql-db-name # Same as in config.production.json
MYSQL_USER: mysql-db-user # Same as in config.production.json
MYSQL_PASSWORD: mysql-db-password # Same as in config.production.json
MYSQL_ROOT_PASSWORD: mysql-db-root-password # Same as in config.production.json
- deploy/02-pvc.yaml # Change the storageClassName as per your requirements
- deploy/03-ingress.yaml # Change the hosts as per your requirements
- deploy/03-service.yaml
- deploy/04-mysql.yaml
- deploy/05-ghost-deployment.yaml
3. Apply your manifests
# Create the namespace
kubectl apply -f deploy/00-namespace.yaml
# Create the secrets
kubectl apply -f deploy/01-secrets.yaml
kubectl apply -f deploy/01-config.production.yaml
# Create the persistent volume
kubectl apply -f deploy/02-pvc.yaml
# Create the ingress
kubectl apply -f deploy/03-ingress.yaml
# Create the services
kubectl apply -f deploy/03-service.yaml
# Create the MySQL database
kubectl apply -f deploy/04-mysql.yaml
# Create the Ghost deployment
kubectl apply -f deploy/05-ghost-deployment.yaml
4. Access your Ghost CMS
# Get the ingress IP address
kubectl get ing -n ghostk3s -o wide