diff --git a/.gitignore b/.gitignore
index a21a015..9144c24 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,4 +45,8 @@ nextjs/**/node_modules/
# Angular
angular/**/.angular
+.env
+.env-*
+!.env-*.example
+
# End of https://www.toptal.com/developers/gitignore/api/macos
\ No newline at end of file
diff --git a/wordpress/wordpress-docker/.github/workflows/main.yaml b/wordpress/wordpress-docker/.github/workflows/main.yaml
new file mode 100644
index 0000000..3ae6a9c
--- /dev/null
+++ b/wordpress/wordpress-docker/.github/workflows/main.yaml
@@ -0,0 +1,42 @@
+name: Deploy
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+
+jobs:
+ deploy:
+ name: Deploy
+ runs-on: ubuntu-latest
+ permissions:
+ contents: 'read'
+ id-token: 'write'
+ if: github.event.pull_request.merged == true || github.event_name == 'push'
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ # ----- KUBERNETES: BUILD and PUBLISH --------------------------#
+ - id: 'auth'
+ uses: 'google-github-actions/auth@v2'
+ with:
+ credentials_json: '${{ secrets.GCP_CREDENTIALS }}' # todo: adjust!
+
+ - name: 'Set up Cloud SDK'
+ uses: 'google-github-actions/setup-gcloud@v2'
+ with:
+ version: '>= 363.0.0'
+
+ - name: 'GKE Credentials'
+ uses: 'google-github-actions/get-gke-credentials@v2'
+ with:
+ cluster_name: 'agung-learn' # todo: adjust!
+ location: 'asia-southeast2-a' # todo: adjust!
+
+ - name: 'Deploy to GKE'
+ run: |
+ kubectl apply -f deploy/k8s -n prod
diff --git a/wordpress/wordpress-docker/README.md b/wordpress/wordpress-docker/README.md
new file mode 100644
index 0000000..45bbcee
--- /dev/null
+++ b/wordpress/wordpress-docker/README.md
@@ -0,0 +1,35 @@
+Wordpress with Docker
+================================
+
+
+## How to Run
+
+### Local
+
+#### Docker
+```shell
+docker compose up -f docker-compose.local.yaml --build -d
+```
+
+### Production
+#### Docker
+```shell
+docker compose up -f --build -d
+```
+
+#### Kubernetes
+```shell
+kubectl apply -f deploy/k8s
+```
+
+### Contributors
+
diff --git a/wordpress/wordpress-docker/deploy/app/.env-app.example b/wordpress/wordpress-docker/deploy/app/.env-app.example
new file mode 100644
index 0000000..f886d16
--- /dev/null
+++ b/wordpress/wordpress-docker/deploy/app/.env-app.example
@@ -0,0 +1,4 @@
+WORDPRESS_DB_HOST=blog_db
+WORDPRESS_DB_USER=gapai_blog_user
+WORDPRESS_DB_PASSWORD=gapai_blog_pass
+WORDPRESS_DB_NAME=gapai_blog_db
\ No newline at end of file
diff --git a/wordpress/wordpress-docker/deploy/app/.env-db.example b/wordpress/wordpress-docker/deploy/app/.env-db.example
new file mode 100644
index 0000000..b55fa87
--- /dev/null
+++ b/wordpress/wordpress-docker/deploy/app/.env-db.example
@@ -0,0 +1,4 @@
+MYSQL_DATABASE=gapai_blog_db
+MYSQL_USER=gapai_blog_user
+MYSQL_PASSWORD=gapai_blog_pass
+MYSQL_ROOT_PASSWORD=gapai_blog_pass
\ No newline at end of file
diff --git a/wordpress/wordpress-docker/deploy/app/Dockerfile b/wordpress/wordpress-docker/deploy/app/Dockerfile
new file mode 100644
index 0000000..e69de29
diff --git a/wordpress/wordpress-docker/deploy/app/nginx/nginx.conf b/wordpress/wordpress-docker/deploy/app/nginx/nginx.conf
new file mode 100644
index 0000000..473deca
--- /dev/null
+++ b/wordpress/wordpress-docker/deploy/app/nginx/nginx.conf
@@ -0,0 +1,13 @@
+upstream app-server {
+ server app:8000;
+}
+
+server {
+ listen 80;
+ location / {
+ proxy_pass http://app-server;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header Host $host;
+ proxy_redirect off;
+ }
+}
\ No newline at end of file
diff --git a/wordpress/wordpress-docker/deploy/k8s/app-deployment.yaml b/wordpress/wordpress-docker/deploy/k8s/app-deployment.yaml
new file mode 100644
index 0000000..de03b4d
--- /dev/null
+++ b/wordpress/wordpress-docker/deploy/k8s/app-deployment.yaml
@@ -0,0 +1,36 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: wordpress-deployment
+spec:
+ selector:
+ matchLabels:
+ component: wordpress-app
+ template:
+ metadata:
+ labels:
+ component: wordpress-app
+ spec:
+ containers:
+ - image: wordpress:6.6.2-apache
+ name: wordpress
+ env:
+ - name: WORDPRESS_DB_HOST
+ value: gapai-blog-db-service
+ - name: WORDPRESS_DB_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: gapai-blog-env
+ key: DB_PASSWORD
+ - name: WORDPRESS_DB_USER
+ value: wordpress
+ ports:
+ - containerPort: 80
+ name: wordpress
+ volumeMounts:
+ - name: gapai-blog-persistent-storage
+ mountPath: /var/www/html
+ volumes:
+ - name: app-persistent-storage
+ persistentVolumeClaim:
+ claimName: app-pv-claim
\ No newline at end of file
diff --git a/wordpress/wordpress-docker/deploy/k8s/app-service.yaml b/wordpress/wordpress-docker/deploy/k8s/app-service.yaml
new file mode 100644
index 0000000..9afe4d5
--- /dev/null
+++ b/wordpress/wordpress-docker/deploy/k8s/app-service.yaml
@@ -0,0 +1,16 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: wordpress-service
+spec:
+# type: ClusterIP
+# ports:
+# - port: 80
+# targetPort: 80
+# selector:
+# app: blog // un-work type ClusterIP
+ ports:
+ - port: 80
+ selector:
+ component: wordpress-app
+ type: LoadBalancer
diff --git a/wordpress/wordpress-docker/deploy/k8s/app-volume.yaml b/wordpress/wordpress-docker/deploy/k8s/app-volume.yaml
new file mode 100644
index 0000000..5b9d6e3
--- /dev/null
+++ b/wordpress/wordpress-docker/deploy/k8s/app-volume.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: gapai-blog-pv-claim
+ namespace: prod
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 3Gi
diff --git a/wordpress/wordpress-docker/deploy/k8s/db-deployment.yaml b/wordpress/wordpress-docker/deploy/k8s/db-deployment.yaml
new file mode 100644
index 0000000..e69de29
diff --git a/wordpress/wordpress-docker/deploy/k8s/db-service.yaml b/wordpress/wordpress-docker/deploy/k8s/db-service.yaml
new file mode 100644
index 0000000..e69de29
diff --git a/wordpress/wordpress-docker/deploy/k8s/db-volume.yaml b/wordpress/wordpress-docker/deploy/k8s/db-volume.yaml
new file mode 100644
index 0000000..e69de29
diff --git a/wordpress/wordpress-docker/deploy/k8s/env.example b/wordpress/wordpress-docker/deploy/k8s/env.example
new file mode 100644
index 0000000..e69de29
diff --git a/wordpress/wordpress-docker/deploy/k8s/nginx-service.yaml b/wordpress/wordpress-docker/deploy/k8s/nginx-service.yaml
new file mode 100644
index 0000000..54df724
--- /dev/null
+++ b/wordpress/wordpress-docker/deploy/k8s/nginx-service.yaml
@@ -0,0 +1,18 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: gatsby-ingress-service
+ annotations:
+ nginx.ingress.kubernetes.io/rewrite-target: /$1
+spec:
+ rules:
+ - host: wordpress.agung96tm.com
+ http:
+ paths:
+ - path: /
+ pathType: Prefix
+ backend:
+ service:
+ name: wordpress-service
+ port:
+ number: 80
diff --git a/wordpress/wordpress-docker/docker-compose.local.yaml b/wordpress/wordpress-docker/docker-compose.local.yaml
new file mode 100644
index 0000000..8852ae5
--- /dev/null
+++ b/wordpress/wordpress-docker/docker-compose.local.yaml
@@ -0,0 +1,36 @@
+version: '3.1'
+
+services:
+ blog:
+ container_name: blog-local-app
+ image: wordpress:6.6.2-apache
+ restart: always
+ ports:
+ - "8080:80"
+ environment:
+ WORDPRESS_DB_HOST: db
+ WORDPRESS_DB_USER: wordpress_user
+ WORDPRESS_DB_PASSWORD: wordpress_password
+ WORDPRESS_DB_NAME: wordpress_db
+ volumes:
+ - blog_app_local_data:/var/www/html
+ depends_on:
+ - db
+
+ db:
+ container_name: blog-local-db
+ image: mariadb:10.5
+ restart: always
+ ports:
+ - "3306:3306"
+ environment:
+ MYSQL_DATABASE: wordpress_db
+ MYSQL_USER: wordpress_user
+ MYSQL_PASSWORD: wordpress_password
+ MYSQL_ROOT_PASSWORD: wordpress_password
+ volumes:
+ - blog_db_local_data:/var/lib/mysql
+
+volumes:
+ blog_app_local_data: {}
+ blog_db_local_data: {}
diff --git a/wordpress/wordpress-docker/docker-compose.yaml b/wordpress/wordpress-docker/docker-compose.yaml
new file mode 100644
index 0000000..875ab48
--- /dev/null
+++ b/wordpress/wordpress-docker/docker-compose.yaml
@@ -0,0 +1,49 @@
+version: '3.1'
+
+services:
+ app:
+ container_name: blog-app
+ image: wordpress:6.6.2-apache
+ restart: always
+ ports:
+ - "8000:80"
+ environment:
+ WORDPRESS_DB_HOST: blog_db
+ WORDPRESS_DB_USER: gapai_blog_user
+ WORDPRESS_DB_PASSWORD: gapai_blog_pass
+ WORDPRESS_DB_NAME: gapai_blog_db
+ volumes:
+ - blog_app_data:/var/www/html
+ depends_on:
+ - db
+ networks:
+ - blog-network
+
+ db:
+ container_name: gapai_blog_db
+ image: mariadb:10.5
+ restart: always
+ ports:
+ - "3306:3306"
+ env_file:
+ - .env-db
+ volumes:
+ - blog_db_data:/var/lib/mysql
+
+ webserver:
+ container_name: gapai_blog_webserver
+ depends_on:
+ - blog
+ image: nginx:1.15.12-alpine
+ restart: unless-stopped
+ ports:
+ - "80:80"
+ - "443:443"
+ volumes:
+ - blog_app_data:/var/www/html
+ - ./deploy/nginx:/etc/nginx/conf.d
+
+volumes:
+ blog_app_data: {}
+ blog_db_data: {}
+