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/backend' OLD_IMAGE = '192.168.49.2:30004/vaishnavi-ecommerce/backend:latest' TAG = "${env.BUILD_NUMBER}" NAMESPACE = 'ecommerce' K8S_DIR = 'k8s/backend' } stages { stage('Build Image') { steps { sh "docker build -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('Apply Namespace') { steps { withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) { sh "kubectl apply -f ${K8S_DIR}/00-namespace.yaml" } } } stage('Apply ConfigMap') { steps { withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) { sh """ sed "s/NODE_IP_PLACEHOLDER/${params.NODE_IP}/g" \ ${K8S_DIR}/configmap.yaml | kubectl apply -f - """ } } } stage('Apply Secret') { steps { withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) { sh "kubectl apply -f ${K8S_DIR}/secret.yaml" } } } stage('Run Migration') { steps { withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) { sh """ kubectl delete job backend-migration -n ${NAMESPACE} --ignore-not-found=true sed "s|${OLD_IMAGE}|${IMAGE}:${TAG}|g" \ ${K8S_DIR}/migration-job.yaml | kubectl apply -f - kubectl wait --for=condition=complete job/backend-migration \ -n ${NAMESPACE} --timeout=120s """ } } } stage('Deploy Backend') { steps { withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) { sh """ sed "s|${OLD_IMAGE}|${IMAGE}:${TAG}|g" \ ${K8S_DIR}/deployment.yaml | kubectl apply -f - kubectl apply -f ${K8S_DIR}/service.yaml kubectl apply -f ${K8S_DIR}/ingress.yaml """ } } } stage('Verify Rollout') { steps { withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) { sh "kubectl rollout status deployment/backend -n ${NAMESPACE} --timeout=180s" } } } stage('Smoke Test') { steps { sh "curl -f http://${params.NODE_IP}:30080/health" } } } post { always { sh "docker rmi ${IMAGE}:${TAG} || true" sh "docker rmi ${IMAGE}:latest || true" } success { echo "Deploy successful. Backend accessible at http://${params.NODE_IP}:30080" } failure { withCredentials([file(credentialsId: 'kubeconfig', variable: 'KUBECONFIG')]) { sh "kubectl get pods -n ${NAMESPACE} || true" sh "kubectl describe deployment/backend -n ${NAMESPACE} || true" } } } }