From 14b4099cdf8d9b142f1fa7824eb54adbf9b18d75 Mon Sep 17 00:00:00 2001 From: tusuii Date: Tue, 10 Mar 2026 22:38:39 +0530 Subject: [PATCH] uploaded k8s and jenkinsfile --- Dockerfile | 13 ++++-- Jenkinsfile | 98 +++++++++++++++++++++++++++++++++++++++++++++ k8s/deployment.yaml | 40 ++++++++++++++++++ k8s/ingress.yaml | 20 +++++++++ k8s/service.yaml | 13 ++++++ nginx.conf | 11 +++++ 6 files changed, 191 insertions(+), 4 deletions(-) create mode 100644 Jenkinsfile create mode 100644 k8s/deployment.yaml create mode 100644 k8s/ingress.yaml create mode 100644 k8s/service.yaml create mode 100644 nginx.conf diff --git a/Dockerfile b/Dockerfile index 4dc4044..3937ccf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # ---------- Build Stage ---------- -FROM node:20-alpine AS builder +FROM mirror.gcr.io/library/node:20-bullseye-slim AS builder WORKDIR /app @@ -8,14 +8,19 @@ RUN npm install COPY . . +ARG VITE_API_URL +ARG VITE_APP_NAME="VC E-Commerce Admin Panel" +ENV VITE_API_URL=$VITE_API_URL +ENV VITE_APP_NAME=$VITE_APP_NAME + RUN npm run build - # ---------- Production Stage ---------- -FROM nginx:alpine +FROM mirror.gcr.io/library/nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html +COPY nginx.conf /etc/nginx/conf.d/default.conf -EXPOSE 5174 +EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..9a738f9 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,98 @@ +pipeline { + agent any + + parameters { + string( + name: 'NODE_IP', + defaultValue: '192.168.108.200', + description: 'On-premise Kubernetes node IP' + ) + } + + environment { + HARBOR = '192.168.108.200:80' + IMAGE = '192.168.108.200:80/vaishnavi-ecommerce/admin' + OLD_IMAGE = '192.168.49.2:30004/vaishnavi-ecommerce/admin:latest' + TAG = "${env.BUILD_NUMBER}" + NAMESPACE = 'ecommerce' + APP_NAME = 'VC E-Commerce Admin Panel' + } + + stages { + stage('Build Image') { + steps { + sh """ + docker build \ + --build-arg VITE_API_URL=http://${params.NODE_IP}:30080/api \ + --build-arg "VITE_APP_NAME=${APP_NAME}" \ + -t ${IMAGE}:${TAG} \ + -t ${IMAGE}:latest \ + . + """ + } + } + + stage('Push to Harbor') { + steps { + withCredentials([usernamePassword( + credentialsId: 'harbor-credentials', + usernameVariable: 'HARBOR_USER', + passwordVariable: 'HARBOR_PASS' + )]) { + sh """ + echo "\$HARBOR_PASS" | docker login ${HARBOR} -u "\$HARBOR_USER" --password-stdin + docker push ${IMAGE}:${TAG} + docker push ${IMAGE}:latest + """ + } + } + } + + stage('Deploy') { + steps { + withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) { + sh """ + sed "s|${OLD_IMAGE}|${IMAGE}:${TAG}|g" \ + k8s/deployment.yaml | kubectl apply -f - + kubectl apply -f k8s/service.yaml + kubectl apply -f k8s/ingress.yaml + """ + } + } + } + + stage('Verify Rollout') { + steps { + withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) { + sh "kubectl rollout status deployment/admin -n ${NAMESPACE} --timeout=180s" + } + } + } + + stage('Smoke Test') { + steps { + sh """ + STATUS=\$(curl -o /dev/null -sw "%{http_code}" http://${params.NODE_IP}:30082) + echo "HTTP status: \$STATUS" + [ "\$STATUS" = "200" ] + """ + } + } + } + + post { + always { + sh "docker rmi ${IMAGE}:${TAG} || true" + sh "docker rmi ${IMAGE}:latest || true" + } + success { + echo "Deploy successful. Admin panel accessible at http://${params.NODE_IP}:30082" + } + failure { + withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) { + sh "kubectl get pods -n ${NAMESPACE} || true" + sh "kubectl describe deployment/admin -n ${NAMESPACE} || true" + } + } + } +} diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml new file mode 100644 index 0000000..2f765c0 --- /dev/null +++ b/k8s/deployment.yaml @@ -0,0 +1,40 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: admin + namespace: ecommerce +spec: + replicas: 1 + selector: + matchLabels: + app: admin + template: + metadata: + labels: + app: admin + spec: + containers: + - name: admin + image: 192.168.49.2:30004/vaishnavi-ecommerce/admin:latest + imagePullPolicy: Always + ports: + - containerPort: 80 + resources: + requests: + cpu: "100m" + memory: "64Mi" + limits: + cpu: "250m" + memory: "128Mi" + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 10 + periodSeconds: 15 + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 5 diff --git a/k8s/ingress.yaml b/k8s/ingress.yaml new file mode 100644 index 0000000..16e403c --- /dev/null +++ b/k8s/ingress.yaml @@ -0,0 +1,20 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: admin-ingress + namespace: ecommerce + annotations: + nginx.ingress.kubernetes.io/proxy-body-size: "10m" +spec: + ingressClassName: nginx + rules: + - host: admin.local + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: admin + port: + number: 80 diff --git a/k8s/service.yaml b/k8s/service.yaml new file mode 100644 index 0000000..84b34c7 --- /dev/null +++ b/k8s/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: admin + namespace: ecommerce +spec: + type: NodePort + selector: + app: admin + ports: + - port: 80 + targetPort: 80 + nodePort: 30082 diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..975971e --- /dev/null +++ b/nginx.conf @@ -0,0 +1,11 @@ +server { + listen 80; + root /usr/share/nginx/html; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + + client_max_body_size 10m; +}