From 28fc47c729a665c73abb4e3402d081f9cca54d3f Mon Sep 17 00:00:00 2001 From: Jonathan Dieu Date: Sat, 15 Aug 2026 18:41:58 -0700 Subject: [PATCH] feat(dieu-dev): workload chart + preview.dieu.dev HTTPRoute Deploys the portfolio site as a workload: a static web frontend and the Go metrics API, served under one hostname (web at /, api at /api via a path-routed HTTPRoute parenting the Cilium public gateway). TLS is terminated by the gateway's *.dieu.dev wildcard, so no per-workload cert is needed. Added to the workloads appset, which targets clusters with purpose in [prod, stage]; only stage is registered today, so it lands there at preview.dieu.dev. A prod override would set hostname dieu.dev. Images reference ghcr.io/jonathandieu/dieu-dev-{web,api}; pushing those from CI to GHCR (currently build-only) is the remaining prerequisite before this can sync. --- argocd/apps/workloads/appset.yaml | 3 ++ charts/workloads/dieu-dev/Chart.yaml | 6 +++ .../dieu-dev/templates/api-deployment.yaml | 42 +++++++++++++++++++ .../dieu-dev/templates/api-service.yaml | 15 +++++++ .../dieu-dev/templates/httproute.yaml | 27 ++++++++++++ .../dieu-dev/templates/web-deployment.yaml | 35 ++++++++++++++++ .../dieu-dev/templates/web-service.yaml | 15 +++++++ charts/workloads/dieu-dev/values.yaml | 39 +++++++++++++++++ 8 files changed, 182 insertions(+) create mode 100644 charts/workloads/dieu-dev/Chart.yaml create mode 100644 charts/workloads/dieu-dev/templates/api-deployment.yaml create mode 100644 charts/workloads/dieu-dev/templates/api-service.yaml create mode 100644 charts/workloads/dieu-dev/templates/httproute.yaml create mode 100644 charts/workloads/dieu-dev/templates/web-deployment.yaml create mode 100644 charts/workloads/dieu-dev/templates/web-service.yaml create mode 100644 charts/workloads/dieu-dev/values.yaml diff --git a/argocd/apps/workloads/appset.yaml b/argocd/apps/workloads/appset.yaml index f1013a8..a339cd4 100644 --- a/argocd/apps/workloads/appset.yaml +++ b/argocd/apps/workloads/appset.yaml @@ -23,6 +23,9 @@ spec: - app: changedetection namespace: changedetection wave: "0" + - app: dieu-dev + namespace: dieu-dev + wave: "0" template: metadata: name: "{{ .app }}-{{ .name }}" diff --git a/charts/workloads/dieu-dev/Chart.yaml b/charts/workloads/dieu-dev/Chart.yaml new file mode 100644 index 0000000..eb2e982 --- /dev/null +++ b/charts/workloads/dieu-dev/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: dieu-dev +description: Portfolio site for dieu.dev (static web + Go metrics API) +type: application +version: 0.1.0 +appVersion: "0.1.0" diff --git a/charts/workloads/dieu-dev/templates/api-deployment.yaml b/charts/workloads/dieu-dev/templates/api-deployment.yaml new file mode 100644 index 0000000..ed90ce1 --- /dev/null +++ b/charts/workloads/dieu-dev/templates/api-deployment.yaml @@ -0,0 +1,42 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-api + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/component: api +spec: + replicas: {{ .Values.api.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/component: api + template: + metadata: + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/component: api + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: api + image: "{{ .Values.api.image.repository }}:{{ .Values.api.image.tag }}" + env: + - name: METRICS_SOURCE + value: {{ .Values.api.metricsSource | quote }} + {{- if .Values.api.prometheusUrl }} + - name: PROMETHEUS_URL + value: {{ .Values.api.prometheusUrl | quote }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.api.port }} + readinessProbe: + httpGet: + path: /healthz + port: http + resources: + {{- toYaml .Values.api.resources | nindent 12 }} diff --git a/charts/workloads/dieu-dev/templates/api-service.yaml b/charts/workloads/dieu-dev/templates/api-service.yaml new file mode 100644 index 0000000..ad7464b --- /dev/null +++ b/charts/workloads/dieu-dev/templates/api-service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-api + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/component: api +spec: + selector: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/component: api + ports: + - name: http + port: {{ .Values.api.port }} + targetPort: http diff --git a/charts/workloads/dieu-dev/templates/httproute.yaml b/charts/workloads/dieu-dev/templates/httproute.yaml new file mode 100644 index 0000000..3914104 --- /dev/null +++ b/charts/workloads/dieu-dev/templates/httproute.yaml @@ -0,0 +1,27 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: {{ .Release.Name }} +spec: + parentRefs: + - name: public + namespace: cilium-gateway-system + hostnames: + - {{ .Values.httproute.hostname | quote }} + rules: + # /api/* -> the Go metrics API (longer prefix wins, so this takes precedence). + - matches: + - path: + type: PathPrefix + value: /api + backendRefs: + - name: {{ .Release.Name }}-api + port: {{ .Values.api.port }} + # everything else -> the static site. + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: {{ .Release.Name }}-web + port: {{ .Values.web.port }} diff --git a/charts/workloads/dieu-dev/templates/web-deployment.yaml b/charts/workloads/dieu-dev/templates/web-deployment.yaml new file mode 100644 index 0000000..055827c --- /dev/null +++ b/charts/workloads/dieu-dev/templates/web-deployment.yaml @@ -0,0 +1,35 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-web + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/component: web +spec: + replicas: {{ .Values.web.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/component: web + template: + metadata: + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/component: web + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: web + image: "{{ .Values.web.image.repository }}:{{ .Values.web.image.tag }}" + ports: + - name: http + containerPort: {{ .Values.web.port }} + readinessProbe: + httpGet: + path: / + port: http + resources: + {{- toYaml .Values.web.resources | nindent 12 }} diff --git a/charts/workloads/dieu-dev/templates/web-service.yaml b/charts/workloads/dieu-dev/templates/web-service.yaml new file mode 100644 index 0000000..18a5610 --- /dev/null +++ b/charts/workloads/dieu-dev/templates/web-service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-web + labels: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/component: web +spec: + selector: + app.kubernetes.io/name: {{ .Release.Name }} + app.kubernetes.io/component: web + ports: + - name: http + port: {{ .Values.web.port }} + targetPort: http diff --git a/charts/workloads/dieu-dev/values.yaml b/charts/workloads/dieu-dev/values.yaml new file mode 100644 index 0000000..8e3f84c --- /dev/null +++ b/charts/workloads/dieu-dev/values.yaml @@ -0,0 +1,39 @@ +# The portfolio site: a static web frontend and a small Go metrics API, served +# together under one hostname (web at /, api at /api). TLS is terminated by the +# Cilium gateway's *.dieu.dev wildcard, so no cert is needed here. + +httproute: + # Per-cluster: stage serves preview.dieu.dev; a prod override would set dieu.dev. + hostname: preview.dieu.dev + +web: + image: + repository: ghcr.io/jonathandieu/dieu-dev-web + tag: latest # pinned by CI/Kargo once images are pushed to GHCR + replicas: 1 + port: 8080 + resources: + requests: + cpu: 10m + memory: 32Mi + limits: + memory: 64Mi + +api: + image: + repository: ghcr.io/jonathandieu/dieu-dev-api + tag: latest # pinned by CI/Kargo once images are pushed to GHCR + replicas: 1 + port: 8080 + # "mock" serves offline fixtures; "prometheus" reads real cluster data. + metricsSource: mock + prometheusUrl: "" + resources: + requests: + cpu: 10m + memory: 16Mi + limits: + memory: 64Mi + +# Set if the GHCR packages are private. +imagePullSecrets: []