Updated jenkinsFile
All checks were successful
DevSecOps-Multibranch/pipeline/head This commit looks good

This commit is contained in:
2025-11-30 12:30:43 +00:00
parent eb85e581f3
commit ecb4417f2f

91
Jenkinsfile vendored
View File

@@ -1,31 +1,33 @@
pipeline { pipeline {
// Run on your specific Agent Droplet // 1. Run heavy lifting (Build/Push) on the Agent
agent { label 'jenkins-agent' } agent { label 'jenkins-agent' }
environment { environment {
// 1. Your ACTUAL Registry Name (Verified) // CRITICAL FIX: Use the Registry Name we verified via 'doctl'
REGISTRY_URL = 'registry.digitalocean.com/devsecops-lab' REGISTRY_URL = 'registry.digitalocean.com/devsecops-lab'
// 2. The ONE allowed repository for Free Tier // CRITICAL FIX: Use 'core' to stay within 1-repo limit
REPO_NAME = 'core' REPO_NAME = 'core'
// 3. Unique Tags to distinguish apps inside the 'core' repo // Dynamic Tags
// Example: core:backend-Dev-25
BACKEND_TAG = "backend-${env.BRANCH_NAME}-${env.BUILD_NUMBER}" BACKEND_TAG = "backend-${env.BRANCH_NAME}-${env.BUILD_NUMBER}"
FRONTEND_TAG = "frontend-${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 { steps { checkout scm }
checkout scm
}
} }
stage('Install Dependencies') { stage('Install Dependencies') {
steps { steps {
echo "Installing dependencies..." echo "Installing dependencies for ${env.BRANCH_NAME}..."
// Ensure these folders exist in your repo! // 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' }
} }
@@ -35,7 +37,6 @@ pipeline {
steps { steps {
script { script {
echo "Building Images..." 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}:${BACKEND_TAG} ./backend"
sh "docker build -t ${REGISTRY_URL}/${REPO_NAME}:${FRONTEND_TAG} ./frontend" sh "docker build -t ${REGISTRY_URL}/${REPO_NAME}:${FRONTEND_TAG} ./frontend"
} }
@@ -44,65 +45,67 @@ pipeline {
stage('Push to Registry') { stage('Push to Registry') {
steps { steps {
// Securely inject the DO Token // We MUST inject the token here, or the push will fail with "Unauthorized"
withCredentials([string(credentialsId: 'do-registry-token', variable: 'DO_TOKEN')]) { withCredentials([string(credentialsId: 'do-registry-token', variable: 'DO_TOKEN')]) {
script { script {
echo "Logging into DigitalOcean Registry..." echo "Logging into Registry..."
// 1. Clean previous state
// 1. NUKE existing config to prevent credential-helper conflicts
sh 'rm -f ~/.docker/config.json' sh 'rm -f ~/.docker/config.json'
// 2. Force Raw Login (Token as Password) // 2. Login using Token as Password
// -u anything works, --password-stdin takes the token sh 'echo $DO_TOKEN | docker login registry.digitalocean.com -u token --password-stdin'
sh 'echo $DO_TOKEN | docker login registry.digitalocean.com -u key_is_token --password-stdin'
echo "Pushing images..." echo "Pushing images..."
sh "docker push ${REGISTRY_URL}/${REPO_NAME}:${BACKEND_TAG}" sh "docker push ${REGISTRY_URL}/${REPO_NAME}:${BACKEND_TAG}"
sh "docker push ${REGISTRY_URL}/${REPO_NAME}:${FRONTEND_TAG}" sh "docker push ${REGISTRY_URL}/${REPO_NAME}:${FRONTEND_TAG}"
// 3. Logout for security // 3. Logout
sh 'docker logout registry.digitalocean.com' sh 'docker logout registry.digitalocean.com'
} }
} }
} }
} }
// --- REMOTE DEPLOYMENT (AGENT -> GITEA SERVER) ---
stage('Deploy') { stage('Deploy') {
steps { steps {
script { script {
// Dynamic Port Assignment based on Branch // Define Ports based on Branch
def appPort = "3000" def appPort = "3000"
if (env.BRANCH_NAME == 'Dev') { appPort = "3001" }
else if (env.BRANCH_NAME == 'Release') { appPort = "3002" }
else if (env.BRANCH_NAME == 'main') { appPort = "3003" }
def containerName = "backend-${env.BRANCH_NAME}" def containerName = "backend-${env.BRANCH_NAME}"
if (env.BRANCH_NAME == 'Dev') { // Define SSH Command using the specific deploy key we created
appPort = "3001" def remote = "ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa_deploy ${DEPLOY_USER}@${DEPLOY_HOST}"
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 echo "Deploying to ${DEPLOY_HOST} on Port ${appPort}..."
try {
sh "docker stop ${containerName} || true" // We need the token again to PULL the image on the remote server
sh "docker rm ${containerName} || true" withCredentials([string(credentialsId: 'do-registry-token', variable: 'DO_TOKEN')]) {
} catch (Exception e) {
echo "No container to stop" // 1. Remote Login
} sh "${remote} 'echo ${DO_TOKEN} | docker login registry.digitalocean.com -u token --password-stdin'"
// 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'"
// 2. Run New Container
sh """ sh """
docker run -d \ ${remote} 'docker run -d \
--name ${containerName} \ --name ${containerName} \
--restart always \ --restart always \
-p ${appPort}:3000 \ -p ${appPort}:3000 \
${REGISTRY_URL}/${REPO_NAME}:${BACKEND_TAG} ${REGISTRY_URL}/${REPO_NAME}:${BACKEND_TAG}'
""" """
echo "SUCCESS: App is live at http://${DEPLOY_HOST}:${appPort}"
}
} }
} }
} }
@@ -110,9 +113,7 @@ pipeline {
post { post {
always { always {
// Cleanup workspace to save disk space // Save disk space on the Agent
deleteDir()
// Cleanup dangling images
sh 'docker system prune -f' sh 'docker system prune -f'
} }
} }