Masdika Loading..
Masdika.BIZ.ID

DevOps Engineer

Cloud Engineer

System Administrator

  • Home
  • Portofolio
  • Services
  • Resume
  • Skills
  • Blog
  • Contact
Masdika.BIZ.ID

DevOps Engineer

Cloud Engineer

System Administrator

Download CV

Recent Posts

  • Cara Deploy WordPress di Kubernetes Lengkap dengan SSL Let’s Encrypt
  • Panduan Lengkap Install MetalLB di Kubernetes (VPS/Bare Metal) dengan IP Publik
  • Panduan Lengkap Deploy Ingress NGINX dan Cert-Manager Kubernetes dengan HTTPS Otomatis (Let’s Encrypt)
  • Cara Install Kubernetes dengan Ansible di 2 Server (Master dan Worker)
  • Monitoring Docker Container dengan CAdvisor, Node Exporter, Prometheus, dan Grafana

Recent Comments

  1. Masdika.BIZ.ID on Cara Install Kubernetes dengan Ansible di 2 Server (Master dan Worker)
  2. wwqqs on Cara Install Kubernetes dengan Ansible di 2 Server (Master dan Worker)
  3. Rio Ardiansyah on Panduan Lengkap Redis Docker untuk WordPress
  4. Masdika.BIZ.ID on Cara Monitoring Status Disk RAID di Server Dell Menggunakan Bash Script dan PercCLI
  5. fafiki on Cara Monitoring Status Disk RAID di Server Dell Menggunakan Bash Script dan PercCLI

Archives

  • July 2025
  • June 2025

Categories

  • Tutorial

Masddika.BIZ.ID

  • About
  • Terms & Conditions
  • Privacy Policy
Blog Post

Cara Deploy WordPress di Kubernetes Lengkap dengan SSL Let’s Encrypt

July 1, 2025 Tutorial by Masdika.BIZ.ID
Cara Deploy WordPress di Kubernetes Lengkap dengan SSL Let’s Encrypt

Tutorial ini menjelaskan langkah demi langkah, termasuk semua konfigurasi YAML, setup penyimpanan, database, hingga penerapan SSL otomatis menggunakan Cert Manager. Cocok untuk pemula maupun yang sudah terbiasa dengan Kubernetes. ✅

📂 Struktur Folder

.
├── cert-manager
│   ├── cert-manager-deploy.yaml
│   ├── cluster-issuer.yaml
│   └── namespace.yaml
├── ingress-nginx
│   ├── ingress-nginx-deploy.yaml
│   ├── ingress-nginx-svc.yaml
│   └── namespace.yaml
├── mysql
│   ├── deployment.yaml
│   ├── pvc.yaml
│   └── service.yaml
├── storage
│   ├── pv.yaml
│   └── storageclass.yaml
└── wordpress
    ├── deployment.yaml
    ├── ingress-www.yaml
    ├── pvc.yaml
    ├── redirect-to-www.yaml
    └── service.yaml

🔥 Penjelasan Detail

📦 Storage

  • storageclass.yaml → Membuat StorageClass bernama local-storage untuk PV lokal.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
  • pv.yaml → Dua PersistentVolume, untuk mysql dan wordpress.
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-mysql
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage
  hostPath:
    path: /root/www.masdika.my.id/data/mysql
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-wordpress
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage
  hostPath:
    path: /root/www.masdika.my.id/data/wordpress

🗄️ MySQL

  • pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage
  resources:
    requests:
      storage: 10Gi
  • deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8
        env:
        - name: MYSQL_DATABASE
          value: wordpress
        - name: MYSQL_USER
          value: wpuser
        - name: MYSQL_PASSWORD
          value: wppassword
        - name: MYSQL_ROOT_PASSWORD
          value: rootpassword
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-data
        persistentVolumeClaim:
          claimName: mysql-pvc
  • service.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  selector:
    app: mysql
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306

🌐 Ingress NGINX

  • namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
  • ingress-nginx-deploy.yaml → Deployment controller nginx
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/component: controller
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/component: controller
    spec:
      serviceAccountName: ingress-nginx
      containers:
      - name: controller
        image: registry.k8s.io/ingress-nginx/controller:v1.10.1
        args:
          - /nginx-ingress-controller
          - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
          - --election-id=ingress-controller-leader
          - --controller-class=k8s.io/ingress-nginx
          - --ingress-class=nginx
          - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
        ports:
          - name: http
            containerPort: 80
          - name: https
            containerPort: 443
  • ingress-nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: LoadBalancer
  selector:
    app.kubernetes.io/name: ingress-nginx
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: https
      port: 443
      targetPort: https

🔐 Cert Manager

  • namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: cert-manager
  • cluster-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@masdika.my.id
    privateKeySecretRef:
      name: letsencrypt-prod-private-key
    solvers:
    - http01:
        ingress:
          class: nginx
  • cert-manager-deploy.yaml
# Apply official manifest
# jalankan perintah:
# kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.0/cert-manager.yaml

🖥️ WordPress

  • pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wordpress-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage
  resources:
    requests:
      storage: 10Gi
  • deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      containers:
      - name: wordpress
        image: wordpress:latest
        env:
        - name: WORDPRESS_DB_HOST
          value: mysql
        - name: WORDPRESS_DB_USER
          value: wpuser
        - name: WORDPRESS_DB_PASSWORD
          value: wppassword
        - name: WORDPRESS_DB_NAME
          value: wordpress
        ports:
        - containerPort: 80
        volumeMounts:
        - name: wordpress-data
          mountPath: /var/www/html
      volumes:
      - name: wordpress-data
        persistentVolumeClaim:
          claimName: wordpress-pvc
  • service.yaml
apiVersion: v1
kind: Service
metadata:
  name: wordpress
spec:
  selector:
    app: wordpress
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  • ingress-www.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: wordpress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - www.masdika.my.id
    secretName: www-masdika-my-id-tls
  rules:
  - host: www.masdika.my.id
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: wordpress
            port:
              number: 80
  • redirect-to-www.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: redirect-to-www
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/permanent-redirect: https://www.masdika.my.id$request_uri
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - masdika.my.id
    secretName: masdika-my-id-tls
  rules:
  - host: masdika.my.id
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: wordpress
            port:
              number: 80

🛠️ Langkah Deploy

1️⃣ Deploy Storage

kubectl apply -f storage/

2️⃣ Deploy MySQL

kubectl apply -f mysql/

3️⃣ Deploy WordPress

kubectl apply -f wordpress/

4️⃣ Deploy Ingress NGINX

kubectl apply -f ingress-nginx/

5️⃣ Deploy Cert Manager

kubectl apply -f cert-manager/namespace.yaml
kubectl apply -f cert-manager/cluster-issuer.yaml
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.0/cert-manager.yaml

(File cert-manager-deploy.yaml menjalankan perintah ke repo resmi cert-manager.)

6️⃣ Deploy Ingress untuk WordPress + Redirect

kubectl apply -f wordpress/redirect-to-www.yaml
kubectl apply -f wordpress/ingress-www.yaml

✅ Akses Domain

  • https://www.masdika.my.id (Utama)
  • https://masdika.my.id (Redirect ke www)

🧠 Troubleshooting

  • 🚫 LoadBalancer Pending → Periksa konfigurasi MetalLB atau cloud provider.
  • 🔐 SSL Error → Pastikan DNS sudah pointing, dan cek ClusterIssuer.
  • ⚠️ PVC Error → Pastikan folder /root/www.masdika.my.id/data/* ada dan permission benar.

🎉 Deployment WordPress di Kubernetes selesai dengan SSL Let’s Encrypt otomatis dan sistem yang production ready!

Share:
Tags: k8skuberneteswordpress

Post navigation

Prev
Write a comment Cancel Reply

© 2025 www.masdika.biz.id — Semua Hak Dilindungi