// Jenkinsfile // Define the Kubernetes agent pod for Kaniko // This specifies a pod with two containers: // 1. 'jnlp': The standard Jenkins agent container to handle checkout and basic shell commands. // 2. 'kaniko': The Kaniko executor container to build Docker images. // We mount the Docker registry secret as a volume. @Library('kubernetes@latest') _ // Assuming you have the Kubernetes Pipeline plugin configured def kanikoPodYaml = """ apiVersion: v1 kind: Pod metadata: labels: app: kaniko-builder spec: containers: - name: jnlp image: jenkins/jnlp-agent:latest workingDir: /home/jenkins/agent args: ['\$(JENKINS_URL)/computer/\$(HOSTNAME)/slave-agent.jnlp'] env: - name: JENKINS_AGENT_SKIP_RETRYONFAILURE value: "true" - name: kaniko image: gcr.io/kaniko-project/executor:debug # Use :debug for shell access, or latest for production command: ["/busybox/cat"] # Keep the container running tty: true volumeMounts: - name: docker-config # Mount the volume with registry credentials mountPath: /kaniko/.docker volumes: - name: docker-config secret: secretName: dockerhub-creds # Name of your Kubernetes secret for Docker registry credentials items: - key: .dockerconfigjson path: config.json """ pipeline { // Agent definition using the Kaniko pod template agent { kubernetes { yaml kanikoPodYaml defaultContainer 'jnlp' // Use 'jnlp' as the default container for checkout and most steps } } environment { // Replace with your Docker registry path and image name // Example for Docker Hub: DOCKER_REGISTRY = "docker.io/your-dockerhub-username" // Example for GCR: DOCKER_REGISTRY = "gcr.io/your-gcp-project-id" // Example for other: DOCKER_REGISTRY = "your-registry.example.com/your-org" DOCKER_REGISTRY = "docker.io/anphamme" // REPLACE WITH YOUR REGISTRY! IMAGE_NAME = "virtualportfolio" IMAGE_TAG = "build-${BUILD_NUMBER}" // Unique tag for each build } stages { stage('Checkout') { steps { script { // This will checkout the code into the default JNLP container's workspace checkout scm } } } stage('Build Docker Image') { steps { // Execute Kaniko inside the 'kaniko' container container('kaniko') { script { // Kaniko needs to access the source code in the shared workspace. // The 'jnlp' container checks out the code to /home/jenkins/agent/workspace/. // Kaniko's context should point to this path. def contextPath = "/home/jenkins/agent/workspace/${env.JOB_NAME}" // Adjust based on your workspace sh """ /kaniko/executor --dockerfile=${contextPath}/Dockerfile \ --context=${contextPath} \ --destination=${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG} \ --skip-tls-verify=false \ --force \ --cache=true \ --cache-dir=/cache """ // --skip-tls-verify=true if you have insecure registry // --force can be useful for initial debugging // --cache and --cache-dir for faster builds (requires persistent volume for cache-dir) } } } } stage('Update Kubernetes Manifests (for Argo CD)') { steps { script { // Assuming you have a separate Git repository for your Kubernetes manifests (GitOps repo) // This is where Argo CD will pick up changes. // For example: https://git.anpham.me/anpham/kubernetes-configs.git // This step is more conceptual. You'd need to: // 1. Checkout the GitOps repository. // 2. Update the image tag in the relevant YAML file (e.g., deployment.yaml or values.yaml if using Helm). // 3. Commit and push the changes back to the GitOps repository. // For demonstration, let's just log the expected image. echo "Image built: ${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}" echo "In a real GitOps setup, this image tag would be committed to a separate Git repo (e.g., your-kubernetes-configs.git)" echo "Argo CD would then detect this change and deploy the new image." // Example (simplified, assuming a 'k8s-manifests' folder in your Jenkins workspace // and a specific deployment.yaml to modify): // You'd need to ensure `git` is available