commit 7268729315281a7dacafde11706ec239dd695477 Author: RobbyDwiJayanto Date: Tue Jul 29 14:32:59 2025 +0700 first commit diff --git a/dockerfile.dockerfile b/dockerfile.dockerfile new file mode 100644 index 0000000..dd67358 --- /dev/null +++ b/dockerfile.dockerfile @@ -0,0 +1,38 @@ +# Dockerfile yang diperbaiki - sesuai dengan struktur repo Anda +FROM wordpress:6.5-php8.2-apache + +# Set working directory +WORKDIR /var/www/html + +# Install tools tambahan dan netcat untuk health check +RUN apt-get update && apt-get install -y \ + unzip \ + curl \ + netcat-traditional \ + less \ + vim \ + && rm -rf /var/lib/apt/lists/* + +# PENTING: Jangan copy seluruh WordPress core files +# Hanya copy custom content dari repo Anda + +# Copy custom themes, plugins, dan content +COPY wp-content /var/www/html/wp-content + +# Copy custom WordPress files jika ada +COPY *.php /var/www/html/ + +# Copy custom .htaccess jika ada +#COPY .htaccess /var/www/html/ 2>/dev/null || true + +# Set permission yang tepat +RUN chown -R www-data:www-data /var/www/html && \ + find /var/www/html -type d -exec chmod 755 {} \; && \ + find /var/www/html -type f -exec chmod 644 {} \; + +# Expose port +EXPOSE 80 + +# Gunakan entrypoint original WordPress dengan custom script +ENTRYPOINT ["docker-entrypoint.sh"] +CMD ["apache2-foreground"] \ No newline at end of file diff --git a/jenkins-deployment.yaml b/jenkins-deployment.yaml new file mode 100644 index 0000000..4bf14b5 --- /dev/null +++ b/jenkins-deployment.yaml @@ -0,0 +1,72 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: jenkins + namespace: jenkins +spec: + replicas: 1 + selector: + matchLabels: + app: jenkins + template: + metadata: + labels: + app: jenkins + spec: + serviceAccountName: jenkins + containers: + - name: jenkins + image: jenkins/jenkins:lts + ports: + - containerPort: 8080 + - containerPort: 50000 + env: + - name: JENKINS_OPTS + value: "--httpPort=8080" + - name: JAVA_OPTS + value: "-Xmx2048m -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85" + securityContext: + runAsUser: 0 + volumeMounts: + - name: jenkins-home + mountPath: /var/jenkins_home + - name: docker-sock + mountPath: /var/run/docker.sock + - name: kubectl-binary + mountPath: /usr/local/bin/kubectl + resources: + requests: + memory: "1Gi" + cpu: "500m" + limits: + memory: "2Gi" + cpu: "1" + volumes: + - name: jenkins-home + persistentVolumeClaim: + claimName: jenkins-pvc + - name: docker-sock + hostPath: + path: /var/run/docker.sock + - name: kubectl-binary + hostPath: + path: /usr/bin/kubectl +--- +apiVersion: v1 +kind: Service +metadata: + name: jenkins + namespace: jenkins + annotations: + metallb.universe.tf/loadBalancerIPs: 10.10.3.233 +spec: + selector: + app: jenkins + ports: + - name: http + port: 8080 + targetPort: 8080 + - name: jnlp + port: 50000 + targetPort: 50000 + type: LoadBalancer \ No newline at end of file diff --git a/jenkins-pvc.yaml b/jenkins-pvc.yaml new file mode 100644 index 0000000..3f8d198 --- /dev/null +++ b/jenkins-pvc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: jenkins-pvc + namespace: jenkins +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Gi + storageClassName: local-path \ No newline at end of file diff --git a/jenkins-rbac.yaml b/jenkins-rbac.yaml new file mode 100644 index 0000000..8e67569 --- /dev/null +++ b/jenkins-rbac.yaml @@ -0,0 +1,40 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: jenkins + namespace: jenkins +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: jenkins +rules: +- apiGroups: [""] + resources: ["pods", "pods/exec", "pods/log", "persistentvolumeclaims", "services", "configmaps", "secrets"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["apps"] + resources: ["deployments", "replicasets", "statefulsets"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: [""] + resources: ["namespaces"] + verbs: ["get", "list"] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: jenkins +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: jenkins +subjects: +- kind: ServiceAccount + name: jenkins + namespace: jenkins \ No newline at end of file diff --git a/jenkinsfile b/jenkinsfile new file mode 100644 index 0000000..0ea931b --- /dev/null +++ b/jenkinsfile @@ -0,0 +1,76 @@ +pipeline { + agent { + kubernetes { + cloud 'kubernetes' + defaultContainer 'kaniko' + yaml """ +apiVersion: v1 +kind: Pod +metadata: + labels: + jenkins-job: kaniko-build +spec: + restartPolicy: Never + + containers: + # ------------ 1) Kaniko (build & push) ------------ + - name: kaniko + image: gcr.io/kaniko-project/executor:debug + command: ["/busybox/sh"] + args: ["-c", "sleep 3600"] + tty: true + env: + - name: DOCKER_CONFIG + value: /kaniko/.docker + volumeMounts: + - name: kaniko-secret + mountPath: /kaniko/.docker + + # ------------ 2) Kubectl (deploy) --------------- + - name: kubectl + image: bitnami/kubectl:latest + command: ["sh", "-c", "sleep 3600"] + tty: true + + volumes: + - name: kaniko-secret + secret: + secretName: regcred +""" + } + + } + environment { + IMAGE = '10.10.3.232:5000/wordpress:latest' + GIT_CTX = 'git://github.com/RobbyDwiJayanto/rentalmotor.git#master' + } + + stages { + stage('Build & Push Image') { + steps { + sh ''' + /kaniko/executor \ + --context=${GIT_CTX} \ + --dockerfile=Dockerfile \ + --destination=${IMAGE} \ + --insecure \ + --skip-tls-verify + ''' + } + } + + stage('Deploy to Cluster') { + steps { + container('kubectl') { + sh 'kubectl apply -f k8s/ -n jenkins' + } + } + } + } + + + post { + always { echo 'Pipeline selesai ✅' } + failure { echo '❌ Build gagal – periksa log!' } + } +} diff --git a/mysql-deployment.yaml b/mysql-deployment.yaml new file mode 100644 index 0000000..fb7892c --- /dev/null +++ b/mysql-deployment.yaml @@ -0,0 +1,48 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mysql + namespace: jenkins +spec: + selector: + matchLabels: + app: mysql + replicas: 1 + template: + metadata: + labels: + app: mysql + spec: + containers: + - name: mysql + image: mysql:5.7 + env: + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: wp-secret + key: mysql_password + - name: MYSQL_DATABASE + valueFrom: + secretKeyRef: + name: wp-secret + key: mysql_database + - name: MYSQL_USER + valueFrom: + secretKeyRef: + name: wp-secret + key: mysql_user + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + name: wp-secret + key: mysql_password + ports: + - containerPort: 3306 + volumeMounts: + - name: mysql-persistent-storage + mountPath: /var/lib/mysql + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pvc \ No newline at end of file diff --git a/mysql-pvc.yaml b/mysql-pvc.yaml new file mode 100644 index 0000000..1ff69ea --- /dev/null +++ b/mysql-pvc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: mysql-pvc + namespace: jenkins +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi + storageClassName: local-path \ No newline at end of file diff --git a/mysql-service.yaml b/mysql-service.yaml new file mode 100644 index 0000000..fa00bae --- /dev/null +++ b/mysql-service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: mysql + namespace: jenkins +spec: + selector: + app: mysql + ports: + - protocol: TCP + port: 3306 + targetPort: 3306 + type: ClusterIP diff --git a/wordpress-deployment.yaml b/wordpress-deployment.yaml new file mode 100644 index 0000000..3d7a088 --- /dev/null +++ b/wordpress-deployment.yaml @@ -0,0 +1,46 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: wordpress + namespace: jenkins +spec: + replicas: 1 + selector: + matchLabels: + app: wordpress + template: + metadata: + labels: + app: wordpress + spec: + containers: + - name: wordpress + image: 10.10.3.232:5000/wordpress:latest + imagePullPolicy: Always + ports: + - containerPort: 80 + env: + - name: WORDPRESS_DB_HOST + value: mysql.jenkins + - name: WORDPRESS_DB_NAME + valueFrom: + secretKeyRef: + name: wp-secret + key: mysql_database + - name: WORDPRESS_DB_USER + valueFrom: + secretKeyRef: + name: wp-secret + key: mysql_user + - name: WORDPRESS_DB_PASSWORD + valueFrom: + secretKeyRef: + name: wp-secret + key: mysql_password + volumeMounts: + - mountPath: /var/www/html/wp-content/upload + name: wordpress-persistent-storage + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: wordpress-pvc \ No newline at end of file diff --git a/wordpress-pvc.yaml b/wordpress-pvc.yaml new file mode 100644 index 0000000..27a39d7 --- /dev/null +++ b/wordpress-pvc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: wordpress-pvc + namespace: jenkins +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + storageClassName: local-path \ No newline at end of file diff --git a/wordpress-service.yaml b/wordpress-service.yaml new file mode 100644 index 0000000..529541f --- /dev/null +++ b/wordpress-service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: wordpress-service + namespace: jenkins + annotations: + metallb.universe.tf/loadBalancerIPs: 10.10.3.235 +spec: + selector: + app: wordpress + ports: + - protocol: TCP + port: 80 + targetPort: 80 + type: LoadBalancer \ No newline at end of file diff --git a/wp-secret.yaml b/wp-secret.yaml new file mode 100644 index 0000000..c7744c8 --- /dev/null +++ b/wp-secret.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: wp-secret + namespace: jenkins +type: Opaque +stringData: + mysql_user: wordpress + mysql_password: supersecret + mysql_database: wordpress \ No newline at end of file