ci: update hello-world app files
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
FROM nginx:alpine
|
||||||
|
|
||||||
|
COPY index.html /usr/share/nginx/html/index.html
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
ENTRYPOINT ["nginx", "-g", "daemon off;"]
|
||||||
Vendored
+129
@@ -0,0 +1,129 @@
|
|||||||
|
// Build -> registry -> deploy, with nothing written back into this repository: Jenkins builds the image with
|
||||||
|
// rootless BuildKit (no privileged docker-in-docker) and pushes it to Harbor as :<commit> and :latest, using the
|
||||||
|
// project's push-only robot account. Argo CD Image Updater (ImageUpdater hello-world in namespace argocd) sees the
|
||||||
|
// new :<commit> tag in Harbor and points the Argo CD application at it. No commit back means no webhook loop, so
|
||||||
|
// no [skip ci] commits and no extra builds.
|
||||||
|
pipeline {
|
||||||
|
agent {
|
||||||
|
kubernetes {
|
||||||
|
label 'buildkit-agent'
|
||||||
|
yaml """
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
spec:
|
||||||
|
serviceAccountName: jenkins
|
||||||
|
containers:
|
||||||
|
- name: buildkit
|
||||||
|
image: moby/buildkit:v0.33.1-rootless
|
||||||
|
command: ['sleep']
|
||||||
|
args: ['99d']
|
||||||
|
env:
|
||||||
|
# Rootless BuildKit inside an unprivileged pod: no process sandbox of its own (the pod is the sandbox).
|
||||||
|
- name: BUILDKITD_FLAGS
|
||||||
|
value: --oci-worker-no-process-sandbox
|
||||||
|
# buildctl and buildkitd are Go: SSL_CERT_DIR adds the internal CA (/certs) to both trust stores, beside the
|
||||||
|
# image's own bundle -- the push talks TLS to Harbor's registry and to its token endpoint.
|
||||||
|
- name: SSL_CERT_DIR
|
||||||
|
value: /etc/ssl/certs:/certs
|
||||||
|
- 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,.demo-06-10-2026.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,.demo-06-10-2026.app.ariki.ai
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 1000
|
||||||
|
runAsGroup: 1000
|
||||||
|
seccompProfile:
|
||||||
|
type: Unconfined
|
||||||
|
appArmorProfile:
|
||||||
|
type: Unconfined
|
||||||
|
volumeMounts:
|
||||||
|
# buildkitd.toml: trust the internal CA for harbor.demo-06-10-2026.app.ariki.ai (ConfigMap hello-world-buildkitd)
|
||||||
|
- name: buildkitd-config
|
||||||
|
mountPath: /home/user/.config/buildkit
|
||||||
|
- name: internal-root-ca
|
||||||
|
mountPath: /certs
|
||||||
|
readOnly: true
|
||||||
|
# Harbor push credentials: the push-only robot (ExternalSecret hello-world-harbor-push)
|
||||||
|
- name: harbor-push
|
||||||
|
mountPath: /home/user/.docker
|
||||||
|
readOnly: true
|
||||||
|
- name: buildkit-state
|
||||||
|
mountPath: /home/user/.local/share/buildkit
|
||||||
|
volumes:
|
||||||
|
- name: buildkitd-config
|
||||||
|
configMap:
|
||||||
|
name: hello-world-buildkitd
|
||||||
|
- name: internal-root-ca
|
||||||
|
secret:
|
||||||
|
secretName: internal-root-ca
|
||||||
|
- name: harbor-push
|
||||||
|
secret:
|
||||||
|
secretName: hello-world-harbor-push
|
||||||
|
items:
|
||||||
|
- key: .dockerconfigjson
|
||||||
|
path: config.json
|
||||||
|
- name: buildkit-state
|
||||||
|
emptyDir: {}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
triggers {
|
||||||
|
GenericTrigger(
|
||||||
|
genericVariables: [
|
||||||
|
[key: 'ref', value: '$.ref'],
|
||||||
|
[key: 'commit_message', value: '$.head_commit.message']
|
||||||
|
],
|
||||||
|
token: 'gitea-webhook'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
environment {
|
||||||
|
HARBOR_HOST = "harbor.demo-06-10-2026.app.ariki.ai"
|
||||||
|
HARBOR_PROJECT = "demo-06-10-2026"
|
||||||
|
IMAGE_NAME = "${HARBOR_HOST}/${HARBOR_PROJECT}/hello-world"
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Build and push image') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
// The commit, not BUILD_NUMBER: unique even if the job is recreated, and it names the source
|
||||||
|
// the image was built from. The ImageUpdater only accepts tags of this shape.
|
||||||
|
env.IMAGE_TAG = env.GIT_COMMIT.take(12)
|
||||||
|
currentBuild.description = env.IMAGE_TAG
|
||||||
|
}
|
||||||
|
container('buildkit') {
|
||||||
|
// buildkitd.toml gives the daemon (blob push) the internal CA; the registry token is fetched by
|
||||||
|
// buildctl itself, which needs it too (--registry-auth-tlscontext), or the push fails with
|
||||||
|
// "failed to fetch oauth token ... x509: certificate signed by unknown authority".
|
||||||
|
sh '''
|
||||||
|
buildctl-daemonless.sh build \
|
||||||
|
--frontend dockerfile.v0 \
|
||||||
|
--local context=. \
|
||||||
|
--local dockerfile=. \
|
||||||
|
--registry-auth-tlscontext "host=${HARBOR_HOST},ca=/certs/ca.crt" \
|
||||||
|
--output "type=image,\\"name=${IMAGE_NAME}:${IMAGE_TAG},${IMAGE_NAME}:latest\\",push=true"
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
success {
|
||||||
|
echo "Pushed ${IMAGE_NAME}:${IMAGE_TAG}; Argo CD Image Updater deploys it to https://hello-world.demo-06-10-2026.app.ariki.ai"
|
||||||
|
}
|
||||||
|
failure {
|
||||||
|
echo "Pipeline failed at: ${env.STAGE_NAME}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Hello World</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Hello from K3s cluster!</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -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.demo-06-10-2026.app.ariki.ai/demo-06-10-2026/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
|
||||||
@@ -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.demo-06-10-2026.app.ariki.ai
|
||||||
|
secretName: hello-world-tls
|
||||||
|
|
||||||
|
rules:
|
||||||
|
- host: hello-world.demo-06-10-2026.app.ariki.ai
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: hello-world
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
# A Kustomize application, so Argo CD Image Updater can set the image tag as an Application override
|
||||||
|
# (spec.source.kustomize.images) instead of anyone committing it into deployment.yml.
|
||||||
|
resources:
|
||||||
|
- deployment.yml
|
||||||
|
- service.yml
|
||||||
|
- ingress.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
|
||||||
Reference in New Issue
Block a user