From 4921c2d9fda272c87b1d75f10d91c4ad407e827c Mon Sep 17 00:00:00 2001
From: "Andrew M. Stoltz" <1578013+astoltz@users.noreply.github.com>
Date: Tue, 10 Mar 2026 01:12:08 -0500
Subject: [PATCH] Fix Traefik dashboard cert issuer: step-ca-acme
---
apps/andrew/andrew.yaml | 274 +++++++++++++++
apps/dustin/dustin.yaml | 274 +++++++++++++++
apps/erik/erik.yaml | 274 +++++++++++++++
apps/fit/fit.yaml | 274 +++++++++++++++
apps/flowercore/flowercore.yaml | 332 ++++++++++++++++++
apps/traefik-dashboard/traefik-dashboard.yaml | 2 +-
6 files changed, 1429 insertions(+), 1 deletion(-)
create mode 100644 apps/andrew/andrew.yaml
create mode 100644 apps/dustin/dustin.yaml
create mode 100644 apps/erik/erik.yaml
create mode 100644 apps/fit/fit.yaml
create mode 100644 apps/flowercore/flowercore.yaml
diff --git a/apps/andrew/andrew.yaml b/apps/andrew/andrew.yaml
new file mode 100644
index 0000000..21ebdda
--- /dev/null
+++ b/apps/andrew/andrew.yaml
@@ -0,0 +1,274 @@
+# Andrew Tenant — bluejay.dev
+# Placeholder landing page served by nginx
+# ArgoCD managed - BlueJay Lab
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: tenant-andrew
+ labels:
+ app.kubernetes.io/part-of: bluejay-infra
+ flowercore.io/tenant: andrew
+---
+# NOTE: The TLS secret cf-origin-bluejay-dev must be created in this namespace
+# separately from a Cloudflare Origin Certificate covering *.bluejay.dev.
+# Create with: kubectl create secret tls cf-origin-bluejay-dev \
+# --cert=bluejay-dev-origin.pem --key=bluejay-dev-origin-key.pem \
+# -n tenant-andrew
+---
+# Landing page HTML
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: andrew-web-html
+ namespace: tenant-andrew
+data:
+ index.html: |
+
+
+
+
+
+ Blue Jay — bluejay.dev
+
+
+
+
+
+
Andrew's Space
+
🐦
+
Blue Jay
+
bluejay.dev
+
+
+
+
+
+
+---
+# nginx configuration
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: andrew-web-nginx-conf
+ namespace: tenant-andrew
+data:
+ default.conf: |
+ server {
+ listen 80;
+ server_name _;
+ root /usr/share/nginx/html;
+ index index.html;
+
+ location / {
+ try_files $uri $uri/ =404;
+ }
+
+ location /healthz {
+ access_log off;
+ return 200 "ok";
+ add_header Content-Type text/plain;
+ }
+ }
+---
+# Deployment
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: andrew-web
+ namespace: tenant-andrew
+ labels:
+ app: andrew-web
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: andrew-web
+ template:
+ metadata:
+ labels:
+ app: andrew-web
+ spec:
+ containers:
+ - name: nginx
+ image: nginx:alpine
+ ports:
+ - containerPort: 80
+ name: http
+ volumeMounts:
+ - name: nginx-conf
+ mountPath: /etc/nginx/conf.d/default.conf
+ subPath: default.conf
+ - name: html
+ mountPath: /usr/share/nginx/html
+ resources:
+ requests:
+ memory: 32Mi
+ cpu: 10m
+ limits:
+ memory: 64Mi
+ cpu: 50m
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: 80
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ readinessProbe:
+ httpGet:
+ path: /healthz
+ port: 80
+ initialDelaySeconds: 3
+ periodSeconds: 5
+ volumes:
+ - name: nginx-conf
+ configMap:
+ name: andrew-web-nginx-conf
+ - name: html
+ configMap:
+ name: andrew-web-html
+---
+# Service
+apiVersion: v1
+kind: Service
+metadata:
+ name: andrew-web
+ namespace: tenant-andrew
+spec:
+ selector:
+ app: andrew-web
+ ports:
+ - port: 80
+ targetPort: 80
+ name: http
+---
+# Traefik IngressRoute — public via Cloudflare
+apiVersion: traefik.io/v1alpha1
+kind: IngressRoute
+metadata:
+ name: andrew-web
+ namespace: tenant-andrew
+spec:
+ entryPoints:
+ - websecure
+ routes:
+ - match: Host(`bluejay.dev`) || Host(`www.bluejay.dev`)
+ kind: Rule
+ services:
+ - name: andrew-web
+ port: 80
+ tls:
+ secretName: cf-origin-bluejay-dev
diff --git a/apps/dustin/dustin.yaml b/apps/dustin/dustin.yaml
new file mode 100644
index 0000000..5a028d3
--- /dev/null
+++ b/apps/dustin/dustin.yaml
@@ -0,0 +1,274 @@
+# Dustin Tenant — timeforta.co
+# Placeholder landing page served by nginx
+# ArgoCD managed - BlueJay Lab
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: tenant-dustin
+ labels:
+ app.kubernetes.io/part-of: bluejay-infra
+ flowercore.io/tenant: dustin
+---
+# NOTE: The TLS secret cf-origin-timeforta-co must be created in this namespace
+# separately from a Cloudflare Origin Certificate covering *.timeforta.co.
+# Create with: kubectl create secret tls cf-origin-timeforta-co \
+# --cert=timeforta-co-origin.pem --key=timeforta-co-origin-key.pem \
+# -n tenant-dustin
+---
+# Landing page HTML
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: dustin-web-html
+ namespace: tenant-dustin
+data:
+ index.html: |
+
+
+
+
+
+ Time For Taco — timeforta.co
+
+
+
+
+
+
Dustin's Space
+
🌮
+
Time For Taco
+
timeforta.co
+
+
+
+
+
+
+---
+# nginx configuration
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: dustin-web-nginx-conf
+ namespace: tenant-dustin
+data:
+ default.conf: |
+ server {
+ listen 80;
+ server_name _;
+ root /usr/share/nginx/html;
+ index index.html;
+
+ location / {
+ try_files $uri $uri/ =404;
+ }
+
+ location /healthz {
+ access_log off;
+ return 200 "ok";
+ add_header Content-Type text/plain;
+ }
+ }
+---
+# Deployment
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: dustin-web
+ namespace: tenant-dustin
+ labels:
+ app: dustin-web
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: dustin-web
+ template:
+ metadata:
+ labels:
+ app: dustin-web
+ spec:
+ containers:
+ - name: nginx
+ image: nginx:alpine
+ ports:
+ - containerPort: 80
+ name: http
+ volumeMounts:
+ - name: nginx-conf
+ mountPath: /etc/nginx/conf.d/default.conf
+ subPath: default.conf
+ - name: html
+ mountPath: /usr/share/nginx/html
+ resources:
+ requests:
+ memory: 32Mi
+ cpu: 10m
+ limits:
+ memory: 64Mi
+ cpu: 50m
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: 80
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ readinessProbe:
+ httpGet:
+ path: /healthz
+ port: 80
+ initialDelaySeconds: 3
+ periodSeconds: 5
+ volumes:
+ - name: nginx-conf
+ configMap:
+ name: dustin-web-nginx-conf
+ - name: html
+ configMap:
+ name: dustin-web-html
+---
+# Service
+apiVersion: v1
+kind: Service
+metadata:
+ name: dustin-web
+ namespace: tenant-dustin
+spec:
+ selector:
+ app: dustin-web
+ ports:
+ - port: 80
+ targetPort: 80
+ name: http
+---
+# Traefik IngressRoute — public via Cloudflare
+apiVersion: traefik.io/v1alpha1
+kind: IngressRoute
+metadata:
+ name: dustin-web
+ namespace: tenant-dustin
+spec:
+ entryPoints:
+ - websecure
+ routes:
+ - match: Host(`timeforta.co`) || Host(`www.timeforta.co`)
+ kind: Rule
+ services:
+ - name: dustin-web
+ port: 80
+ tls:
+ secretName: cf-origin-timeforta-co
diff --git a/apps/erik/erik.yaml b/apps/erik/erik.yaml
new file mode 100644
index 0000000..bda8a35
--- /dev/null
+++ b/apps/erik/erik.yaml
@@ -0,0 +1,274 @@
+# Erik Tenant — erckak.dev
+# Placeholder landing page served by nginx
+# ArgoCD managed - BlueJay Lab
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: tenant-erik
+ labels:
+ app.kubernetes.io/part-of: bluejay-infra
+ flowercore.io/tenant: erik
+---
+# NOTE: The TLS secret cf-origin-erckak-dev must be created in this namespace
+# separately from a Cloudflare Origin Certificate covering *.erckak.dev.
+# Create with: kubectl create secret tls cf-origin-erckak-dev \
+# --cert=erckak-dev-origin.pem --key=erckak-dev-origin-key.pem \
+# -n tenant-erik
+---
+# Landing page HTML
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: erik-web-html
+ namespace: tenant-erik
+data:
+ index.html: |
+
+
+
+
+
+ Erckak — erckak.dev
+
+
+
+
+
+
Erik's Space
+
🚀
+
Erckak
+
erckak.dev
+
+
+
+
+
+
+---
+# nginx configuration
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: erik-web-nginx-conf
+ namespace: tenant-erik
+data:
+ default.conf: |
+ server {
+ listen 80;
+ server_name _;
+ root /usr/share/nginx/html;
+ index index.html;
+
+ location / {
+ try_files $uri $uri/ =404;
+ }
+
+ location /healthz {
+ access_log off;
+ return 200 "ok";
+ add_header Content-Type text/plain;
+ }
+ }
+---
+# Deployment
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: erik-web
+ namespace: tenant-erik
+ labels:
+ app: erik-web
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: erik-web
+ template:
+ metadata:
+ labels:
+ app: erik-web
+ spec:
+ containers:
+ - name: nginx
+ image: nginx:alpine
+ ports:
+ - containerPort: 80
+ name: http
+ volumeMounts:
+ - name: nginx-conf
+ mountPath: /etc/nginx/conf.d/default.conf
+ subPath: default.conf
+ - name: html
+ mountPath: /usr/share/nginx/html
+ resources:
+ requests:
+ memory: 32Mi
+ cpu: 10m
+ limits:
+ memory: 64Mi
+ cpu: 50m
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: 80
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ readinessProbe:
+ httpGet:
+ path: /healthz
+ port: 80
+ initialDelaySeconds: 3
+ periodSeconds: 5
+ volumes:
+ - name: nginx-conf
+ configMap:
+ name: erik-web-nginx-conf
+ - name: html
+ configMap:
+ name: erik-web-html
+---
+# Service
+apiVersion: v1
+kind: Service
+metadata:
+ name: erik-web
+ namespace: tenant-erik
+spec:
+ selector:
+ app: erik-web
+ ports:
+ - port: 80
+ targetPort: 80
+ name: http
+---
+# Traefik IngressRoute — public via Cloudflare
+apiVersion: traefik.io/v1alpha1
+kind: IngressRoute
+metadata:
+ name: erik-web
+ namespace: tenant-erik
+spec:
+ entryPoints:
+ - websecure
+ routes:
+ - match: Host(`erckak.dev`) || Host(`www.erckak.dev`)
+ kind: Rule
+ services:
+ - name: erik-web
+ port: 80
+ tls:
+ secretName: cf-origin-erckak-dev
diff --git a/apps/fit/fit.yaml b/apps/fit/fit.yaml
new file mode 100644
index 0000000..5bec59b
--- /dev/null
+++ b/apps/fit/fit.yaml
@@ -0,0 +1,274 @@
+# FIT Tenant — flowerinsider.xyz
+# Placeholder landing page served by nginx
+# ArgoCD managed - BlueJay Lab
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: tenant-fit
+ labels:
+ app.kubernetes.io/part-of: bluejay-infra
+ flowercore.io/tenant: fit
+---
+# NOTE: The TLS secret cf-origin-flowerinsider-xyz must be created in this namespace
+# separately from a Cloudflare Origin Certificate covering *.flowerinsider.xyz.
+# Create with: kubectl create secret tls cf-origin-flowerinsider-xyz \
+# --cert=flowerinsider-xyz-origin.pem --key=flowerinsider-xyz-origin-key.pem \
+# -n tenant-fit
+---
+# Landing page HTML
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: fit-web-html
+ namespace: tenant-fit
+data:
+ index.html: |
+
+
+
+
+
+ Flower Insider — flowerinsider.xyz
+
+
+
+
+
+
Flower Insider Team
+
🌸
+
Flower Insider
+
flowerinsider.xyz
+
+
+
+
+
+
+---
+# nginx configuration
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: fit-web-nginx-conf
+ namespace: tenant-fit
+data:
+ default.conf: |
+ server {
+ listen 80;
+ server_name _;
+ root /usr/share/nginx/html;
+ index index.html;
+
+ location / {
+ try_files $uri $uri/ =404;
+ }
+
+ location /healthz {
+ access_log off;
+ return 200 "ok";
+ add_header Content-Type text/plain;
+ }
+ }
+---
+# Deployment
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: fit-web
+ namespace: tenant-fit
+ labels:
+ app: fit-web
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: fit-web
+ template:
+ metadata:
+ labels:
+ app: fit-web
+ spec:
+ containers:
+ - name: nginx
+ image: nginx:alpine
+ ports:
+ - containerPort: 80
+ name: http
+ volumeMounts:
+ - name: nginx-conf
+ mountPath: /etc/nginx/conf.d/default.conf
+ subPath: default.conf
+ - name: html
+ mountPath: /usr/share/nginx/html
+ resources:
+ requests:
+ memory: 32Mi
+ cpu: 10m
+ limits:
+ memory: 64Mi
+ cpu: 50m
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: 80
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ readinessProbe:
+ httpGet:
+ path: /healthz
+ port: 80
+ initialDelaySeconds: 3
+ periodSeconds: 5
+ volumes:
+ - name: nginx-conf
+ configMap:
+ name: fit-web-nginx-conf
+ - name: html
+ configMap:
+ name: fit-web-html
+---
+# Service
+apiVersion: v1
+kind: Service
+metadata:
+ name: fit-web
+ namespace: tenant-fit
+spec:
+ selector:
+ app: fit-web
+ ports:
+ - port: 80
+ targetPort: 80
+ name: http
+---
+# Traefik IngressRoute — public via Cloudflare
+apiVersion: traefik.io/v1alpha1
+kind: IngressRoute
+metadata:
+ name: fit-web
+ namespace: tenant-fit
+spec:
+ entryPoints:
+ - websecure
+ routes:
+ - match: Host(`flowerinsider.xyz`) || Host(`www.flowerinsider.xyz`)
+ kind: Rule
+ services:
+ - name: fit-web
+ port: 80
+ tls:
+ secretName: cf-origin-flowerinsider-xyz
diff --git a/apps/flowercore/flowercore.yaml b/apps/flowercore/flowercore.yaml
new file mode 100644
index 0000000..cf2ad40
--- /dev/null
+++ b/apps/flowercore/flowercore.yaml
@@ -0,0 +1,332 @@
+# FlowerCore Tenant — flowercore.io (main brand)
+# Public-facing placeholder landing page served by nginx
+# ArgoCD managed - BlueJay Lab
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: tenant-flowercore
+ labels:
+ app.kubernetes.io/part-of: bluejay-infra
+ flowercore.io/tenant: flowercore
+---
+# NOTE: The existing cf-origin-flowercore-io secret (covering *.flowercore.io)
+# must be copied into this namespace. It already exists in other namespaces.
+# Copy with: kubectl get secret cf-origin-flowercore-io -n fc-system -o yaml \
+# | sed 's/namespace: .*/namespace: tenant-flowercore/' \
+# | kubectl apply -f -
+---
+# Landing page HTML
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: flowercore-web-html
+ namespace: tenant-flowercore
+data:
+ index.html: |
+
+
+
+
+
+ FlowerCore — flowercore.io
+
+
+
+
+
+
Platform
+
🌻
+
FlowerCore
+
flowercore.io
+
+ Multi-tenant service management platform.
+ Digital signage, telephony, MySQL hosting, and more.
+
+
+
+
+
Digital Signage
+
Screens, zones, scheduling
+
+
+
Telephony
+
IVR workflows, Twilio
+
+
+
MySQL Manager
+
Database provisioning
+
+
+
PHP Manager
+
Site deployment
+
+
+
+
+
+
+
+---
+# nginx configuration
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: flowercore-web-nginx-conf
+ namespace: tenant-flowercore
+data:
+ default.conf: |
+ server {
+ listen 80;
+ server_name _;
+ root /usr/share/nginx/html;
+ index index.html;
+
+ location / {
+ try_files $uri $uri/ =404;
+ }
+
+ location /healthz {
+ access_log off;
+ return 200 "ok";
+ add_header Content-Type text/plain;
+ }
+ }
+---
+# Deployment
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: flowercore-web
+ namespace: tenant-flowercore
+ labels:
+ app: flowercore-web
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: flowercore-web
+ template:
+ metadata:
+ labels:
+ app: flowercore-web
+ spec:
+ containers:
+ - name: nginx
+ image: nginx:alpine
+ ports:
+ - containerPort: 80
+ name: http
+ volumeMounts:
+ - name: nginx-conf
+ mountPath: /etc/nginx/conf.d/default.conf
+ subPath: default.conf
+ - name: html
+ mountPath: /usr/share/nginx/html
+ resources:
+ requests:
+ memory: 32Mi
+ cpu: 10m
+ limits:
+ memory: 64Mi
+ cpu: 50m
+ livenessProbe:
+ httpGet:
+ path: /healthz
+ port: 80
+ initialDelaySeconds: 5
+ periodSeconds: 10
+ readinessProbe:
+ httpGet:
+ path: /healthz
+ port: 80
+ initialDelaySeconds: 3
+ periodSeconds: 5
+ volumes:
+ - name: nginx-conf
+ configMap:
+ name: flowercore-web-nginx-conf
+ - name: html
+ configMap:
+ name: flowercore-web-html
+---
+# Service
+apiVersion: v1
+kind: Service
+metadata:
+ name: flowercore-web
+ namespace: tenant-flowercore
+spec:
+ selector:
+ app: flowercore-web
+ ports:
+ - port: 80
+ targetPort: 80
+ name: http
+---
+# Traefik IngressRoute — public via Cloudflare
+# Uses existing cf-origin-flowercore-io cert (must be copied to this namespace)
+apiVersion: traefik.io/v1alpha1
+kind: IngressRoute
+metadata:
+ name: flowercore-web
+ namespace: tenant-flowercore
+spec:
+ entryPoints:
+ - websecure
+ routes:
+ - match: Host(`flowercore.io`) || Host(`www.flowercore.io`)
+ kind: Rule
+ services:
+ - name: flowercore-web
+ port: 80
+ tls:
+ secretName: cf-origin-flowercore-io
diff --git a/apps/traefik-dashboard/traefik-dashboard.yaml b/apps/traefik-dashboard/traefik-dashboard.yaml
index 93fdcae..632a850 100644
--- a/apps/traefik-dashboard/traefik-dashboard.yaml
+++ b/apps/traefik-dashboard/traefik-dashboard.yaml
@@ -50,7 +50,7 @@ metadata:
spec:
secretName: traefik-tls
issuerRef:
- name: step-ca-issuer
+ name: step-ca-acme
kind: ClusterIssuer
dnsNames:
- traefik.iamworkin.lan