commit 73b9a2d815397fc0e301a38e9415159a46de090d Author: Ansible Date: Tue Sep 22 16:15:27 2026 +0200 ci: update hello-world app files diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6eb4d34 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,5 @@ +FROM nginx:alpine + +COPY index.html /usr/share/nginx/html/index.html + +EXPOSE 80 \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..01b140b --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,162 @@ +pipeline { + agent { + kubernetes { + label 'docker-agent' + yaml """ +apiVersion: v1 +kind: Pod +spec: + serviceAccountName: jenkins + containers: + - name: docker + image: docker:dind + securityContext: + privileged: true + env: + - name: DOCKER_TLS_CERTDIR + value: "" + - name: HTTP_PROXY + value: http://10.0.10.10:3128 + - name: HTTPS_PROXY + value: http://10.0.10.10:3128 + - name: NO_PROXY + value: localhost,127.0.0.1,10.0.0.0/8,.cluster.local,.svc,.knapp-world.app.ariki.ai + - name: http_proxy + value: http://10.0.10.10:3128 + - name: https_proxy + value: http://10.0.10.10:3128 + - name: no_proxy + value: localhost,127.0.0.1,10.0.0.0/8,.cluster.local,.svc,.knapp-world.app.ariki.ai + volumeMounts: + - name: docker-storage + mountPath: /var/lib/docker + - name: harbor-ca + mountPath: /etc/docker/certs.d/harbor.knapp-world.app.ariki.ai/ca.crt + subPath: ca.crt + - name: tools + image: alpine/git:latest + command: ['sleep'] + args: ['99d'] + ttyEnabled: true + volumes: + - name: docker-storage + emptyDir: {} + - name: harbor-ca + secret: + secretName: internal-root-ca +""" + } + } + + triggers { + GenericTrigger( + genericVariables: [ + [key: 'ref', value: '$.ref'], + [key: 'commit_message', value: '$.head_commit.message'] + ], + token: 'gitea-webhook' + ) + } + + environment { + HARBOR_HOST = "harbor.knapp-world.app.ariki.ai" + HARBOR_PROJECT = "knapp-world" + IMAGE_NAME = "${HARBOR_HOST}/${HARBOR_PROJECT}/hello-world" + IMAGE_TAG = "${BUILD_NUMBER}" + GITEA_HOST = "gitea.knapp-world.app.ariki.ai" + GITEA_REPO = "admin/hello-world" + } + + stages { + + stage('Skip CI commit') { + when { + expression { + return env.commit_message?.contains('[skip ci]') + } + } + steps { + script { + currentBuild.result = 'NOT_BUILT' + error('Skipping Jenkins-generated commit') + } + } + } + + stage('Build Image') { + steps { + container('docker') { + sh """ + # Wait for docker daemon to be ready + for i in \$(seq 1 30); do + docker info > /dev/null 2>&1 && break + echo "Waiting for Docker daemon... \$i" + sleep 2 + done + docker build -t ${IMAGE_NAME}:${IMAGE_TAG} -t ${IMAGE_NAME}:latest . + """ + } + } + } + + stage('Push to Harbor') { + steps { + container('docker') { + withCredentials([usernamePassword( + credentialsId: 'harbor-credentials', + usernameVariable: 'HARBOR_USER', + passwordVariable: 'HARBOR_PASS' + )]) { + sh """ + docker login ${HARBOR_HOST} -u \${HARBOR_USER} -p \${HARBOR_PASS} + docker push ${IMAGE_NAME}:${IMAGE_TAG} + docker push ${IMAGE_NAME}:latest + """ + } + } + } + } + + stage('Update Manifest and Push') { + steps { + container('tools') { + withCredentials([usernamePassword( + credentialsId: 'gitea-credentials', + usernameVariable: 'GIT_USER', + passwordVariable: 'GIT_PASS' + )]) { + sh """ + set -e + + cd "$WORKSPACE" + git config --global --add safe.directory "$WORKSPACE" + + pwd + git status + + git config user.email "jenkins@local" + git config user.name "Jenkins" + + # Update image tag in deployment manifest + sed -i "s|image: ${IMAGE_NAME}:.*|image: ${IMAGE_NAME}:${IMAGE_TAG}|" k8s/deployment.yml + + git add k8s/deployment.yml + git diff --staged --quiet && echo "No changes to commit" && exit 0 + git commit -m "ci: update image to build ${IMAGE_TAG} [skip ci]" + git push https://\${GIT_USER}:\${GIT_PASS}@${GITEA_HOST}/${GITEA_REPO}.git HEAD:main + """ + } + } + } + } + } + + post { + success { + echo "Build ${BUILD_NUMBER} deployed — https://hello-world.knapp-world.app.ariki.ai" + } + failure { + echo "Pipeline failed at: ${env.STAGE_NAME}" + } + } +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..9093078 --- /dev/null +++ b/index.html @@ -0,0 +1,9 @@ + + + + Hello World + + +

Hello from K3s cluster!

+ + \ No newline at end of file diff --git a/k8s/deployment.yml b/k8s/deployment.yml new file mode 100644 index 0000000..a35cf83 --- /dev/null +++ b/k8s/deployment.yml @@ -0,0 +1,35 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: hello-world + namespace: hello-world +spec: + replicas: 2 + selector: + matchLabels: + app: hello-world + template: + metadata: + labels: + app: hello-world + spec: + imagePullSecrets: + - name: harbor-pull-secret + containers: + - name: hello-world + image: harbor.knapp-world.app.ariki.ai/knapp-world/hello-world:latest + ports: + - containerPort: 80 + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + cpu: 100m + memory: 128Mi + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 5 \ No newline at end of file diff --git a/k8s/ingress.yml b/k8s/ingress.yml new file mode 100644 index 0000000..2248a8f --- /dev/null +++ b/k8s/ingress.yml @@ -0,0 +1,23 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: hello-world + namespace: hello-world +spec: + ingressClassName: nginx + tls: + - hosts: + - hello-world.knapp-world.app.ariki.ai + secretName: hello-world-tls + + rules: + - host: hello-world.knapp-world.app.ariki.ai + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: hello-world + port: + number: 80 diff --git a/k8s/service.yml b/k8s/service.yml new file mode 100644 index 0000000..b287a5f --- /dev/null +++ b/k8s/service.yml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: hello-world + namespace: hello-world +spec: + selector: + app: hello-world + ports: + - port: 80 + targetPort: 80