pipeline { agent any environment { REMOTE_HOST = '192.168.1.102' REMOTE_DIR = '/home/zouklambadabcn.com/public_html' PM2_APP = 'ZLB' // Name of Jenkins Credentials (Username with private key) to SSH SSH_CREDS = 'ssh-remote' // <-- configure this in Jenkins Credentials } options { ansiColor('xterm') timestamps() } stages { stage('Deploy over SSH') { steps { script { // Validate Jenkins has the required credential withCredentials([sshUserPrivateKey(credentialsId: env.SSH_CREDS, keyFileVariable: 'SSH_KEY', usernameVariable: 'SSH_USER')]) { // Build the remote command to run def remoteCmd = """ set -euo pipefail cd "${env.REMOTE_DIR}" echo "[$(date)] PWD=$(pwd) on ${HOSTNAME}" # Ensure repo is cleanly updated git fetch --all --prune git reset --hard HEAD git pull --rebase --autostash || git pull # Use npm if available, fallback to npx if needed if command -v npm >/dev/null 2>&1; then npm ci || npm install npm run build else npx --yes npm@latest ci || npx --yes npm@latest install npx --yes npm@latest run build fi # Restart pm2 app if command -v pm2 >/dev/null 2>&1; then pm2 restart "${PM2_APP}" || pm2 start npm --name "${PM2_APP}" -- run start pm2 save || true else echo 'pm2 not found in PATH' >&2 exit 1 fi """.stripIndent() // SSH options for non-interactive, secure connection def sshOpts = '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes' // Execute remote command via ssh sh label: 'Run remote deployment', script: "ssh -i \"${SSH_KEY}\" ${sshOpts} \"${SSH_USER}@${REMOTE_HOST}\" 'bash -lc '\''" + remoteCmd.replace("'", "'\''") + "'\'' '" } } } } } post { success { echo 'Deployment completed successfully.' } failure { echo 'Deployment failed.' } always { cleanWs(deleteDirs: true, notFailBuild: true) } } }