diff --git a/apps/demo b/apps/demo deleted file mode 100644 index efae0ff..0000000 --- a/apps/demo +++ /dev/null @@ -1,348 +0,0 @@ -// Declarative Jenkins Pipeline definition -pipeline { - - // Jenkins can execute this pipeline on any available agent/node - agent any - - // Global environment variables available in all stages - environment { - - // Logical application name - // Used in Docker image name, Kubernetes deployment, labels, logs - APP_NAME = 'demo-nginx' - - // Kubernetes namespace where the application is deployed - NAMESPACE = 'demo-app' - - // Docker registry hostname - DOCKER_REGISTRY = 'docker.io' - - // Docker Hub repository / namespace (Docker Hub username or org) - DOCKER_REPO = 'vladcrypto' - - // Internal Gitea service URL (cluster-internal DNS) - GITEA_URL = 'http://gitea-http.gitea.svc.cluster.local:3000' - - // Git repository path inside Gitea - GITEA_REPO = 'admin/k3s-gitops' - - // Branch used for GitOps updates - GITEA_BRANCH = 'main' - - // Jenkins build number (unique per run) - BUILD_TAG = "${env.BUILD_NUMBER}" - - // Image tag composed of: - // - branch name (e.g. main, feature-x) - // - Jenkins build number - // Ensures traceability and uniqueness - IMAGE_TAG = "${env.BRANCH_NAME}-${env.BUILD_NUMBER}" - } - - stages { - - // ============================ - // STAGE: Generate application source - // ============================ - stage('Checkout Source') { - steps { - - // Log message in Jenkins console - echo "Checking out application source code..." - - // Shell block to generate Dockerfile dynamically - sh ''' - # Create Dockerfile in workspace - cat > Dockerfile << 'EOF' - -# Use lightweight official Nginx Alpine image -FROM nginx:1.25.3-alpine - -# Replace default Nginx index page -# Embed Jenkins build number and image tag directly into HTML -RUN echo "\ -

Demo Nginx - Build ${BUILD_NUMBER}

\ -

Environment: Production

\ -

Version: ${IMAGE_TAG}

\ -" > /usr/share/nginx/html/index.html - -# Copy custom Nginx configuration into container -COPY nginx.conf /etc/nginx/nginx.conf - -# Expose HTTP port (documentation only, runtime handled by Kubernetes) -EXPOSE 80 - -# Run Nginx in foreground (required for containers) -CMD ["nginx", "-g", "daemon off;"] - -EOF - ''' - - // Shell block to generate nginx.conf dynamically - sh ''' - # Create Nginx configuration file - cat > nginx.conf << 'EOF' - -# User under which Nginx worker processes run -user nginx; - -# Automatically scale workers to CPU cores -worker_processes auto; - -# Error log configuration -error_log /var/log/nginx/error.log warn; - -# PID file location -pid /var/run/nginx.pid; - -# Event handling configuration -events { - # Maximum number of simultaneous connections per worker - worker_connections 1024; -} - -http { - # Load MIME types - include /etc/nginx/mime.types; - - # Default MIME type - default_type application/octet-stream; - - # Define access log format - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - - # Enable access logging - access_log /var/log/nginx/access.log main; - - # Enable zero-copy file transfers - sendfile on; - - # Keepalive timeout for client connections - keepalive_timeout 65; - - # HTTP server definition - server { - - # Listen on port 80 - listen 80; - - # Default catch-all server name - server_name _; - - # Root location serving static content - location / { - root /usr/share/nginx/html; - index index.html; - } - - # Health endpoint for Kubernetes probes - location /health { - # Disable access logs for health checks - access_log off; - - # Always return HTTP 200 - return 200 "healthy\n"; - - # Explicit content type - add_header Content-Type text/plain; - } - } -} - -EOF - ''' - } - } - - // ============================ - // STAGE: Build Docker image - // ============================ - stage('Build Docker Image') { - steps { - script { - - // Log which image is being built - echo "Building Docker image: ${DOCKER_REGISTRY}/${DOCKER_REPO}/${APP_NAME}:${IMAGE_TAG}" - - // Build Docker image - sh """ - docker build \ - # Versioned image tag - -t ${DOCKER_REGISTRY}/${DOCKER_REPO}/${APP_NAME}:${IMAGE_TAG} \ - # Latest tag for convenience - -t ${DOCKER_REGISTRY}/${DOCKER_REPO}/${APP_NAME}:latest \ - # Build context = current workspace - . - """ - - // Success marker - echo "✅ Image built successfully!" - } - } - } - - // ============================ - // STAGE: Push image to registry - // ============================ - stage('Push to Registry') { - - // Execute this stage ONLY on main branch - when { branch 'main' } - - steps { - script { - - echo "Pushing image to registry..." - - // Inject Docker registry credentials from Jenkins - withCredentials([usernamePassword( - credentialsId: 'docker-registry-credentials', - usernameVariable: 'DOCKER_USER', - passwordVariable: 'DOCKER_PASS' - )]) { - - sh """ - # Login to Docker registry using stdin (secure) - echo "\${DOCKER_PASS}" | docker login ${DOCKER_REGISTRY} \ - -u "\${DOCKER_USER}" --password-stdin - - # Push versioned image - docker push ${DOCKER_REGISTRY}/${DOCKER_REPO}/${APP_NAME}:${IMAGE_TAG} - - # Push latest tag - docker push ${DOCKER_REGISTRY}/${DOCKER_REPO}/${APP_NAME}:latest - - # Logout for security hygiene - docker logout ${DOCKER_REGISTRY} - """ - } - - echo "✅ Image pushed successfully!" - } - } - } - - // ============================ - // STAGE: Update GitOps manifests - // ============================ - stage('Update GitOps Manifests') { - - // GitOps updates only from main branch - when { branch 'main' } - - steps { - script { - - echo "Updating Kubernetes manifests..." - - // Inject Gitea credentials - withCredentials([usernamePassword( - credentialsId: 'gitea-credentials', - usernameVariable: 'GIT_USER', - passwordVariable: 'GIT_PASS' - )]) { - - sh """ - # Remove previous repo clone if exists - rm -rf k3s-gitops || true - - # Clone GitOps repository with credentials - git clone http://\${GIT_USER}:\${GIT_PASS}@gitea-http.gitea.svc.cluster.local:3000/admin/k3s-gitops.git - - # Enter repository directory - cd k3s-gitops - - # Configure Git identity for Jenkins commits - git config user.name "Jenkins" - git config user.email "jenkins@thedevops.dev" - - # Update image field in Kubernetes Deployment manifest - sed -i 's|image: .*|image: ${DOCKER_REGISTRY}/${DOCKER_REPO}/${APP_NAME}:${IMAGE_TAG}|' \ - apps/demo-nginx/deployment.yaml - - # Stage changed file - git add apps/demo-nginx/deployment.yaml - - # Commit change (ignore if no diff) - git commit -m "chore(demo-nginx): Update image to ${IMAGE_TAG}" || echo "No changes" - - # Push change to main branch - git push origin main - """ - } - - echo "✅ Manifests updated!" - } - } - } - - // ============================ - // STAGE: Verify Kubernetes deployment - // ============================ - stage('Verify Deployment') { - - // Only verify deployments from main - when { branch 'main' } - - steps { - script { - - echo "Verifying deployment..." - - sh """ - # Give Kubernetes time to start rollout - sleep 30 - - # Check rollout status (do not fail pipeline hard) - kubectl rollout status deployment/${APP_NAME} \ - -n ${NAMESPACE} --timeout=300s || true - - # List pods for visibility - kubectl get pods -n ${NAMESPACE} -l app=${APP_NAME} - """ - - echo "✅ Deployment completed!" - } - } - } - } - - // ============================ - // POST actions (always executed) - // ============================ - post { - - // On successful pipeline execution - success { - echo """ - ✅ Pipeline SUCCESS! - Image: ${DOCKER_REGISTRY}/${DOCKER_REPO}/${APP_NAME}:${IMAGE_TAG} - Namespace: ${NAMESPACE} - """ - } - - // On pipeline failure - failure { - echo "❌ Pipeline failed!" - } - - // Always executed (success or failure) - always { - - // Cleanup local Docker images to free disk space - sh """ - docker rmi ${DOCKER_REGISTRY}/${DOCKER_REPO}/${APP_NAME}:${IMAGE_TAG} || true - docker rmi ${DOCKER_REGISTRY}/${DOCKER_REPO}/${APP_NAME}:latest || true - - # Stop and remove any temporary test containers - docker stop test-${BUILD_NUMBER} 2>/dev/null || true - docker rm test-${BUILD_NUMBER} 2>/dev/null || true - """ - - // Clean Jenkins workspace directory - cleanWs() - } - } -}