pipeline { // 1. Run all heavy lifting (builds) on the dedicated Agent agent { label 'jenkins-agent' } environment { // --- REGISTRY & REPOSITORY FIXES --- REGISTRY_URL = 'registry.digitalocean.com/devsecops-lab' REPO_NAME = 'core' // Single repository for Free Tier // --- TAGS --- BACKEND_TAG = "backend-${env.BRANCH_NAME}-${env.BUILD_NUMBER}" FRONTEND_TAG = "frontend-${env.BRANCH_NAME}-${env.BUILD_NUMBER}" // --- DEPLOYMENT TARGET --- DEPLOY_HOST = 'gitea.kongseng.in' DEPLOY_USER = 'root' } stages { stage('Checkout') { steps { checkout scm } } stage('Install Dependencies') { steps { echo "Installing dependencies for ${env.BRANCH_NAME} branch..." // Assuming Node is installed on the agent dir('backend') { sh 'npm install' } dir('frontend') { sh 'npm install' } } } stage('Build Docker Images') { steps { script { echo "Building Backend & Frontend Images..." sh "docker build -t ${REGISTRY_URL}/${REPO_NAME}:${BACKEND_TAG} ./backend" sh "docker build -t ${REGISTRY_URL}/${REPO_NAME}:${FRONTEND_TAG} ./frontend" } } } stage('Push to Registry') { steps { withCredentials([string(credentialsId: 'do-registry-token', variable: 'DO_TOKEN')]) { script { echo "Logging into DigitalOcean Registry..." // Clean login for robustness sh 'rm -f ~/.docker/config.json' sh 'echo $DO_TOKEN | docker login registry.digitalocean.com -u token --password-stdin' echo "Pushing images..." sh "docker push ${REGISTRY_URL}/${REPO_NAME}:${BACKEND_TAG}" sh "docker push ${REGISTRY_URL}/${REPO_NAME}:${FRONTEND_TAG}" sh 'docker logout registry.digitalocean.com' } } } } stage('Remote Deploy') { steps { script { echo "--- REMOTE DEPLOYMENT STARTED ---" // 1. Define Dynamic Ports and Names def backPort = "3000" def frontPort = "4000" if (env.BRANCH_NAME == 'Dev') { backPort = "3001"; frontPort = "4001"; } else if (env.BRANCH_NAME == 'Release') { backPort = "3002"; frontPort = "4002"; } else if (env.BRANCH_NAME == 'main') { backPort = "3003"; frontPort = "4003"; } def backName = "backend-${env.BRANCH_NAME}" def frontName = "frontend-${env.BRANCH_NAME}" // 2. Define SSH Command using the specific deploy key def remote = "ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa_deploy ${DEPLOY_USER}@${DEPLOY_HOST}" // 3. Authenticate and Deploy BOTH Containers withCredentials([string(credentialsId: 'do-registry-token', variable: 'DO_TOKEN')]) { // Remote Login (Gitea Server needs to pull) sh "${remote} 'echo ${DO_TOKEN} | docker login registry.digitalocean.com -u token --password-stdin'" // --- BACKEND DEPLOYMENT (Primary Service) --- echo "Deploying Backend to Port ${backPort}..." sh "${remote} 'docker pull ${REGISTRY_URL}/${REPO_NAME}:${BACKEND_TAG}'" sh "${remote} 'docker stop ${backName} || true'" sh "${remote} 'docker rm ${backName} || true'" sh """ ${remote} 'docker run -d \ --name ${backName} \ --restart always \ -p ${backPort}:3001 \ ${REGISTRY_URL}/${REPO_NAME}:${BACKEND_TAG}' """ // --- FRONTEND DEPLOYMENT (Secondary Service) --- echo "Deploying Frontend to Port ${frontPort}..." sh "${remote} 'docker pull ${REGISTRY_URL}/${REPO_NAME}:${FRONTEND_TAG}'" sh "${remote} 'docker stop ${frontName} || true'" sh "${remote} 'docker rm ${frontName} || true'" sh """ ${remote} 'docker run -d \ --name ${frontName} \ --restart always \ -p ${frontPort}:80 \ ${REGISTRY_URL}/${REPO_NAME}:${FRONTEND_TAG}' """ sh 'docker logout registry.digitalocean.com' echo "Deployment Complete! Backend: http://${DEPLOY_HOST}:${backPort}, Frontend: http://${DEPLOY_HOST}:${frontPort}" } } } } } post { always { // Cleanup: Delete source code and clean Docker cache on the Agent echo 'Cleaning Agent workspace...' deleteDir() sh 'docker system prune -f' } } }