From 6e47a5186bd016ecc6695ec0c0fcca1943f084da Mon Sep 17 00:00:00 2001 From: Nicholas Ward Date: Tue, 4 Aug 2026 16:39:36 -0500 Subject: [PATCH] deploy personal website with k3s --- .gitea/workflows/build-and-push-image.yml | 34 ++++++++++++ k8s/deployment.yaml | 63 +++++++++++++++++++++++ k8s/ingress.yaml | 19 +++++++ k8s/kustomization.yaml | 10 ++++ k8s/service.yaml | 15 ++++++ 5 files changed, 141 insertions(+) create mode 100644 k8s/deployment.yaml create mode 100644 k8s/ingress.yaml create mode 100644 k8s/kustomization.yaml create mode 100644 k8s/service.yaml diff --git a/.gitea/workflows/build-and-push-image.yml b/.gitea/workflows/build-and-push-image.yml index ff5af0b..63152ac 100644 --- a/.gitea/workflows/build-and-push-image.yml +++ b/.gitea/workflows/build-and-push-image.yml @@ -30,6 +30,40 @@ jobs: - name: ๐Ÿš€ Push Docker image run: docker push $IMAGE_REGISTRY/$IMAGE_NAME:$IMAGE_TAG + + - name: Install kubectl + env: + KUBECTL_VERSION: v1.36.2 + run: | + set -euo pipefail + curl -fsSLO "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl" + curl -fsSLO "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl.sha256" + printf '%s %s\n' "$(cat kubectl.sha256)" kubectl | sha256sum --check + sudo install -m 0755 kubectl /usr/local/bin/kubectl + + - name: Configure Kubernetes access + env: + KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }} + run: | + set -euo pipefail + mkdir -p ~/.kube + printf '%s' "$KUBE_CONFIG" | base64 --decode > ~/.kube/config + chmod 600 ~/.kube/config + kubectl auth can-i update deployments --namespace nicholas + + - name: Deploy personal website + run: | + set -euo pipefail + sed -E -i "s#newTag: [0-9a-f]+#newTag: ${IMAGE_TAG}#" k8s/kustomization.yaml + grep -q "newTag: ${IMAGE_TAG}$" k8s/kustomization.yaml + kubectl apply --kustomize k8s + if ! kubectl rollout status deployment/personal-website \ + --namespace nicholas --timeout=180s; then + kubectl rollout undo deployment/personal-website --namespace nicholas + kubectl rollout status deployment/personal-website \ + --namespace nicholas --timeout=180s + exit 1 + fi - name: ๐Ÿงน Prune images if: always() diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml new file mode 100644 index 0000000..246526b --- /dev/null +++ b/k8s/deployment.yaml @@ -0,0 +1,63 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: personal-website + labels: + app.kubernetes.io/name: personal-website +spec: + replicas: 2 + revisionHistoryLimit: 5 + progressDeadlineSeconds: 180 + strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + maxSurge: 1 + selector: + matchLabels: + app.kubernetes.io/name: personal-website + template: + metadata: + labels: + app.kubernetes.io/name: personal-website + spec: + imagePullSecrets: + - name: gitea-registry + containers: + - name: personal-website + image: git.uuard.com/nicholas/personal-website + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: 8080 + protocol: TCP + readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 2 + periodSeconds: 5 + timeoutSeconds: 2 + failureThreshold: 6 + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 2 + failureThreshold: 3 + resources: + requests: + cpu: 10m + memory: 32Mi + limits: + cpu: 100m + memory: 128Mi + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + runAsUser: 101 + runAsGroup: 101 + seccompProfile: + type: RuntimeDefault diff --git a/k8s/ingress.yaml b/k8s/ingress.yaml new file mode 100644 index 0000000..bd1092a --- /dev/null +++ b/k8s/ingress.yaml @@ -0,0 +1,19 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: personal-website + labels: + app.kubernetes.io/name: personal-website +spec: + ingressClassName: traefik + rules: + - host: nicholas.uuard.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: personal-website + port: + name: http diff --git a/k8s/kustomization.yaml b/k8s/kustomization.yaml new file mode 100644 index 0000000..5bd3903 --- /dev/null +++ b/k8s/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: nicholas +resources: + - deployment.yaml + - service.yaml + - ingress.yaml +images: + - name: git.uuard.com/nicholas/personal-website + newTag: 4db91d3ceb2b2378c805bf494701715e1c19d2ce diff --git a/k8s/service.yaml b/k8s/service.yaml new file mode 100644 index 0000000..5dda2b7 --- /dev/null +++ b/k8s/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: personal-website + labels: + app.kubernetes.io/name: personal-website +spec: + type: ClusterIP + selector: + app.kubernetes.io/name: personal-website + ports: + - name: http + port: 80 + targetPort: http + protocol: TCP