pipeline { // Run on your specific Agent Droplet agent { label 'jenkins-agent' } environment { // 1. Your ACTUAL Registry Name (Verified) REGISTRY_URL = 'registry.digitalocean.com/devsecops-lab' // 2. The ONE allowed repository for Free Tier REPO_NAME = 'core' // 3. Unique Tags to distinguish apps inside the 'core' repo // Example: core:backend-Dev-25 BACKEND_TAG = "backend-${env.BRANCH_NAME}-${env.BUILD_NUMBER}" FRONTEND_TAG = "frontend-${env.BRANCH_NAME}-${env.BUILD_NUMBER}" } stages { stage('Checkout') { steps { checkout scm } } stage('Install Dependencies') { steps { echo "Installing dependencies..." // Ensure these folders exist in your repo! dir('backend') { sh 'npm install' } dir('frontend') { sh 'npm install' } } } stage('Build Docker Images') { steps { script { echo "Building Images..." // Build using the 'core' repo path but unique tags 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 { // Securely inject the DO Token withCredentials([string(credentialsId: 'do-registry-token', variable: 'DO_TOKEN')]) { script { echo "Logging into DigitalOcean Registry..." // 1. NUKE existing config to prevent credential-helper conflicts sh 'rm -f ~/.docker/config.json' // 2. Force Raw Login (Token as Password) // -u anything works, --password-stdin takes the token sh 'echo $DO_TOKEN | docker login registry.digitalocean.com -u key_is_token --password-stdin' echo "Pushing images..." sh "docker push ${REGISTRY_URL}/${REPO_NAME}:${BACKEND_TAG}" sh "docker push ${REGISTRY_URL}/${REPO_NAME}:${FRONTEND_TAG}" // 3. Logout for security sh 'docker logout registry.digitalocean.com' } } } } stage('Deploy') { steps { script { // Dynamic Port Assignment based on Branch def appPort = "3000" def containerName = "backend-${env.BRANCH_NAME}" if (env.BRANCH_NAME == 'Dev') { appPort = "3001" echo "Deploying to DEV (Port 3001)" } else if (env.BRANCH_NAME == 'Release') { appPort = "3002" echo "Deploying to STAGING (Port 3002)" } else if (env.BRANCH_NAME == 'main') { appPort = "3003" echo "Deploying to PRODUCTION (Port 3003)" } // 1. Cleanup Old Container try { sh "docker stop ${containerName} || true" sh "docker rm ${containerName} || true" } catch (Exception e) { echo "No container to stop" } // 2. Run New Container sh """ docker run -d \ --name ${containerName} \ --restart always \ -p ${appPort}:3000 \ ${REGISTRY_URL}/${REPO_NAME}:${BACKEND_TAG} """ } } } } post { always { // Cleanup workspace to save disk space deleteDir() // Cleanup dangling images sh 'docker system prune -f' } } }