pipeline { agent { label 'jenkins-master' } tools { // If you have Docker tool configured in Jenkins docker 'Default' } // Environment variables environment { COMPOSE_PROJECT_NAME = "${env.JOB_NAME}-${env.BUILD_NUMBER}" DOCKER_COMPOSE_FILE = 'docker-compose.yml' } stages { stage('Cleanup') { steps { // Clean workspace before build cleanWs() // Stop any existing containers sh 'docker-compose down --remove-orphans || true' } } stage('Build') { steps { script { try { sh 'docker-compose build --no-cache' } catch (err) { error "Failed to build Docker images: ${err}" } } } } stage('Test') { steps { script { try { // Run tests and capture the output sh ''' docker-compose run --rm app python -m pytest \ --junitxml=test-results/junit.xml \ --cov=app \ --cov-report=xml:coverage-reports/coverage.xml ''' } catch (err) { error "Tests failed: ${err}" } } } post { always { // Publish test results even if tests fail junit allowEmptyResults: true, testResults: 'test-results/*.xml' // Publish coverage reports publishCoverage adapters: [coberturaAdapter('coverage-reports/coverage.xml')] } } } stage('Security Scan') { steps { script { try { // Run security scanning on Docker images sh 'docker scan app:latest || true' } catch (err) { // Don't fail the build but warn about security issues warning "Security scan found issues: ${err}" } } } } stage('Deploy') { steps { script { try { // Take backup of current deployment state sh 'docker-compose ps > deployment-state.txt || true' // Deploy with health check sh ''' docker-compose up -d # Wait for containers to be healthy ./scripts/wait-for-healthy.sh 300 ''' } catch (err) { // If deployment fails, attempt rollback error "Deployment failed: ${err}" } } } } } post { always { script { // Cleanup resources regardless of build result sh ''' # Save logs before cleanup mkdir -p logs docker-compose logs > logs/docker-compose.log || true # Cleanup docker-compose down --remove-orphans || true docker system prune -f || true ''' // Archive logs and deployment state archiveArtifacts artifacts: 'logs/*, deployment-state.txt', allowEmptyArchive: true } } success { echo 'Pipeline completed successfully!' // Add notifications for success (email, Slack, etc.) } failure { echo 'Pipeline failed!' // Add notifications for failure (email, Slack, etc.) } } options { // Set timeout for entire pipeline timeout(time: 1, unit: 'HOURS') // Keep build logs and artifacts for 10 builds buildDiscarder(logRotator(numToKeepStr: '10')) // Don't run concurrent builds disableConcurrentBuilds() } }