|
@ -0,0 +1,114 @@ |
|
|
|
|
|
// 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/<job-name>. |
|
|
|
|
|
// 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 |