2 Commits

Author SHA1 Message Date
3c513989ae Push main branch code to Release branch
Some checks failed
DevSecOps-Multibranch/pipeline/head There was a failure building this commit
2025-11-30 15:29:04 +05:30
049326a8fe Clear all files from Release branch 2025-11-30 15:28:46 +05:30

141
Jenkinsfile vendored
View File

@@ -1,33 +1,26 @@
pipeline { pipeline {
// 1. Run heavy lifting (Build/Push) on the Agent // 1. Run on your specific agent
agent { label 'jenkins-agent' } agent { label 'jenkins-agent' }
environment { environment {
// CRITICAL FIX: Use the Registry Name we verified via 'doctl' REGISTRY_URL = 'registry.digitalocean.com/kongseng'
REGISTRY_URL = 'registry.digitalocean.com/devsecops-lab'
// CRITICAL FIX: Use 'core' to stay within 1-repo limit // 2. Dynamic Naming: Image tag includes Branch Name to prevent conflicts
REPO_NAME = 'core' // Example: registry.../backend:Dev-42 or registry.../backend:main-42
BACKEND_IMAGE = "${REGISTRY_URL}/devsecops-backend:${env.BRANCH_NAME}-${env.BUILD_NUMBER}"
// Dynamic Tags FRONTEND_IMAGE = "${REGISTRY_URL}/devsecops-frontend:${env.BRANCH_NAME}-${env.BUILD_NUMBER}"
BACKEND_TAG = "backend-${env.BRANCH_NAME}-${env.BUILD_NUMBER}"
FRONTEND_TAG = "frontend-${env.BRANCH_NAME}-${env.BUILD_NUMBER}"
// Deployment Target (The Gitea Server)
DEPLOY_HOST = 'gitea.kongseng.in'
DEPLOY_USER = 'root'
} }
stages { stages {
stage('Checkout') { stage('Checkout') {
steps { checkout scm } steps {
checkout scm
}
} }
stage('Install Dependencies') { stage('Install Dependencies') {
steps { steps {
echo "Installing dependencies for ${env.BRANCH_NAME}..." echo "Installing dependencies for ${env.BRANCH_NAME} branch..."
// Ensure folders exist to avoid errors
sh 'ls -la'
dir('backend') { sh 'npm install' } dir('backend') { sh 'npm install' }
dir('frontend') { sh 'npm install' } dir('frontend') { sh 'npm install' }
} }
@@ -36,85 +29,71 @@ pipeline {
stage('Build Docker Images') { stage('Build Docker Images') {
steps { steps {
script { script {
echo "Building Images..." echo "Building Images for branch: ${env.BRANCH_NAME}..."
sh "docker build -t ${REGISTRY_URL}/${REPO_NAME}:${BACKEND_TAG} ./backend" sh "docker build -t ${BACKEND_IMAGE} ./backend"
sh "docker build -t ${REGISTRY_URL}/${REPO_NAME}:${FRONTEND_TAG} ./frontend" sh "docker build -t ${FRONTEND_IMAGE} ./frontend"
} }
} }
} }
stage('Push to Registry') { stage('Push to Registry') {
steps { steps {
// We MUST inject the token here, or the push will fail with "Unauthorized" script {
withCredentials([string(credentialsId: 'do-registry-token', variable: 'DO_TOKEN')]) { echo "Pushing images to DigitalOcean..."
script { sh "docker push ${BACKEND_IMAGE}"
echo "Logging into Registry..." sh "docker push ${FRONTEND_IMAGE}"
// 1. Clean previous state
sh 'rm -f ~/.docker/config.json'
// 2. Login using Token as Password
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}"
// 3. Logout
sh 'docker logout registry.digitalocean.com'
}
} }
} }
} }
// --- REMOTE DEPLOYMENT (AGENT -> GITEA SERVER) --- // --- DYNAMIC DEPLOYMENT ---
stage('Deploy') { stage('Deploy') {
steps { steps {
script { script {
// Define Ports based on Branch // Define ports and names based on the branch
def appPort = "3000" def appPort = "3000" // Fallback
if (env.BRANCH_NAME == 'Dev') { appPort = "3001" } def containerName = "backend-app"
else if (env.BRANCH_NAME == 'Release') { appPort = "3002" }
else if (env.BRANCH_NAME == 'main') { appPort = "3003" } if (env.BRANCH_NAME == 'Dev') {
appPort = "3001"
def containerName = "backend-${env.BRANCH_NAME}" containerName = "backend-dev"
echo "Deploying to DEV Environment (Port 3001)"
// Define SSH Command using the specific deploy key we created }
def remote = "ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa_deploy ${DEPLOY_USER}@${DEPLOY_HOST}" else if (env.BRANCH_NAME == 'Release') {
appPort = "3002"
echo "Deploying to ${DEPLOY_HOST} on Port ${appPort}..." containerName = "backend-release"
echo "Deploying to STAGING Environment (Port 3002)"
// We need the token again to PULL the image on the remote server }
withCredentials([string(credentialsId: 'do-registry-token', variable: 'DO_TOKEN')]) { else if (env.BRANCH_NAME == 'main') {
appPort = "3003"
// 1. Remote Login containerName = "backend-prod"
sh "${remote} 'echo ${DO_TOKEN} | docker login registry.digitalocean.com -u token --password-stdin'" echo "Deploying to PRODUCTION Environment (Port 3003)"
// 2. Remote Pull
sh "${remote} 'docker pull ${REGISTRY_URL}/${REPO_NAME}:${BACKEND_TAG}'"
// 3. Remote Restart (Stop -> Remove -> Run)
sh "${remote} 'docker stop ${containerName} || true'"
sh "${remote} 'docker rm ${containerName} || true'"
sh """
${remote} 'docker run -d \
--name ${containerName} \
--restart always \
-p ${appPort}:3000 \
${REGISTRY_URL}/${REPO_NAME}:${BACKEND_TAG}'
"""
echo "SUCCESS: App is live at http://${DEPLOY_HOST}:${appPort}"
} }
else {
// Logic for any future feature branches
appPort = "3004"
containerName = "backend-feature-${env.BRANCH_NAME}"
echo "Deploying Feature Branch"
}
// 1. Clean up 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 on the assigned port
sh """
docker run -d \
--name ${containerName} \
--restart always \
-p ${appPort}:3000 \
${BACKEND_IMAGE}
"""
} }
} }
} }
} }
}
post {
always {
// Save disk space on the Agent
sh 'docker system prune -f'
}
}
}