diff --git a/apps/fc-landing/fc-landing.yaml b/apps/fc-landing/fc-landing.yaml
new file mode 100644
index 0000000..d606df3
--- /dev/null
+++ b/apps/fc-landing/fc-landing.yaml
@@ -0,0 +1,248 @@
+# FlowerCore Landing Page
+# Blue Jay Lab branded landing page
+# ArgoCD managed - BlueJay Lab
+---
+# fc-system namespace is shared; don't overwrite if it exists
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: fc-system
+ labels:
+ app.kubernetes.io/part-of: bluejay-infra
+---
+# Landing page HTML
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: fc-landing-html
+ namespace: fc-system
+data:
+ index.html: |
+
+
+
+
+
BlueJay PKI Portal
+
IAmWorkin ACME Certificate Authority
+
+
Internal CA
+
ClusterIssuer: step-ca-acme
+
Domain: *.iamworkin.lan
+
Validity: 30 days, auto-renewed by cert-manager
+
+
+
Cloudflare Origin Certs
+
*.flowercore.io and *.iamwork.in
+
15-year RSA certificates for public domains
+
+
+
Download Root CA
+
Install the IAmWorkin Root CA certificate to trust internal services.
+
Root CA download will be available here.
+
+
+
+
+---
+# nginx configuration
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: pki-web-nginx-conf
+ namespace: pki
+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;
+ }
+ }
+---
+# PKI Web Deployment
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: pki-web
+ namespace: pki
+ labels:
+ app: pki-web
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: pki-web
+ template:
+ metadata:
+ labels:
+ app: pki-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: 16Mi
+ cpu: 5m
+ 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: pki-web-nginx-conf
+ - name: html
+ configMap:
+ name: pki-web-html
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: pki-web
+ namespace: pki
+spec:
+ selector:
+ app: pki-web
+ ports:
+ - port: 80
+ targetPort: 80
+ name: http
+---
+# TLS Certificate via cert-manager
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+ name: pki-tls
+ namespace: pki
+spec:
+ secretName: pki-tls
+ issuerRef:
+ name: step-ca-acme
+ kind: ClusterIssuer
+ dnsNames:
+ - pki.iamworkin.lan
+---
+# Traefik IngressRoute
+apiVersion: traefik.io/v1alpha1
+kind: IngressRoute
+metadata:
+ name: pki-web
+ namespace: pki
+spec:
+ entryPoints:
+ - websecure
+ routes:
+ - match: Host(`pki.iamworkin.lan`)
+ kind: Rule
+ services:
+ - name: pki-web
+ port: 80
+ tls:
+ secretName: pki-tls
diff --git a/apps/teamspeak/teamspeak.yaml b/apps/teamspeak/teamspeak.yaml
new file mode 100644
index 0000000..7dcdd38
--- /dev/null
+++ b/apps/teamspeak/teamspeak.yaml
@@ -0,0 +1,108 @@
+# TeamSpeak 3 Server
+# ArgoCD managed - BlueJay Lab
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: teamspeak
+ labels:
+ app.kubernetes.io/part-of: bluejay-infra
+---
+# TeamSpeak data PVC
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: teamspeak-data
+ namespace: teamspeak
+spec:
+ accessModes: [ReadWriteOnce]
+ resources:
+ requests:
+ storage: 1Gi
+---
+# TeamSpeak 3 Deployment
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: teamspeak
+ namespace: teamspeak
+ labels:
+ app: teamspeak
+spec:
+ replicas: 1
+ strategy:
+ type: Recreate
+ selector:
+ matchLabels:
+ app: teamspeak
+ template:
+ metadata:
+ labels:
+ app: teamspeak
+ spec:
+ containers:
+ - name: teamspeak
+ image: teamspeak:latest
+ ports:
+ - containerPort: 9987
+ name: voice
+ protocol: UDP
+ - containerPort: 30033
+ name: filetransfer
+ protocol: TCP
+ - containerPort: 10011
+ name: serverquery
+ protocol: TCP
+ env:
+ - name: TS3SERVER_LICENSE
+ value: accept
+ volumeMounts:
+ - name: teamspeak-data
+ mountPath: /var/ts3server
+ resources:
+ requests:
+ memory: 128Mi
+ cpu: 50m
+ limits:
+ memory: 512Mi
+ cpu: 500m
+ readinessProbe:
+ tcpSocket:
+ port: 10011
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ livenessProbe:
+ tcpSocket:
+ port: 10011
+ initialDelaySeconds: 60
+ periodSeconds: 15
+ volumes:
+ - name: teamspeak-data
+ persistentVolumeClaim:
+ claimName: teamspeak-data
+---
+# TeamSpeak LoadBalancer Service
+apiVersion: v1
+kind: Service
+metadata:
+ name: teamspeak
+ namespace: teamspeak
+ annotations:
+ metallb.universe.tf/loadBalancerIPs: 10.0.56.205
+spec:
+ type: LoadBalancer
+ selector:
+ app: teamspeak
+ ports:
+ - port: 9987
+ targetPort: 9987
+ name: voice
+ protocol: UDP
+ - port: 30033
+ targetPort: 30033
+ name: filetransfer
+ protocol: TCP
+ - port: 10011
+ targetPort: 10011
+ name: serverquery
+ protocol: TCP
diff --git a/apps/zabbix/zabbix.yaml b/apps/zabbix/zabbix.yaml
new file mode 100644
index 0000000..f394b09
--- /dev/null
+++ b/apps/zabbix/zabbix.yaml
@@ -0,0 +1,320 @@
+# Zabbix 7.2 Monitoring Stack
+# PostgreSQL 16 + Zabbix Server + Zabbix Web (nginx)
+# ArgoCD managed - BlueJay Lab
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: zabbix
+ labels:
+ app.kubernetes.io/part-of: bluejay-infra
+---
+apiVersion: v1
+kind: Secret
+metadata:
+ name: zabbix-db-secret
+ namespace: zabbix
+type: Opaque
+stringData:
+ POSTGRES_USER: zabbix
+ POSTGRES_PASSWORD: BlueJay-ZabbixDB-2026
+ POSTGRES_DB: zabbix
+---
+apiVersion: v1
+kind: Secret
+metadata:
+ name: zabbix-admin-secret
+ namespace: zabbix
+type: Opaque
+stringData:
+ ZBX_ADMIN_PASSWORD: BlueJay-NOC-2026
+---
+# PostgreSQL 16 StatefulSet
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: zabbix-postgres
+ namespace: zabbix
+ labels:
+ app: zabbix-postgres
+spec:
+ serviceName: zabbix-postgres
+ replicas: 1
+ selector:
+ matchLabels:
+ app: zabbix-postgres
+ template:
+ metadata:
+ labels:
+ app: zabbix-postgres
+ spec:
+ containers:
+ - name: postgres
+ image: postgres:16-alpine
+ ports:
+ - containerPort: 5432
+ name: postgres
+ envFrom:
+ - secretRef:
+ name: zabbix-db-secret
+ volumeMounts:
+ - name: zabbix-postgres-data
+ mountPath: /var/lib/postgresql/data
+ subPath: pgdata
+ resources:
+ requests:
+ memory: 256Mi
+ cpu: 100m
+ limits:
+ memory: 512Mi
+ cpu: 500m
+ livenessProbe:
+ exec:
+ command:
+ - pg_isready
+ - -U
+ - zabbix
+ initialDelaySeconds: 30
+ periodSeconds: 10
+ readinessProbe:
+ exec:
+ command:
+ - pg_isready
+ - -U
+ - zabbix
+ initialDelaySeconds: 5
+ periodSeconds: 5
+ volumeClaimTemplates:
+ - metadata:
+ name: zabbix-postgres-data
+ spec:
+ accessModes: [ReadWriteOnce]
+ resources:
+ requests:
+ storage: 10Gi
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: zabbix-postgres
+ namespace: zabbix
+spec:
+ selector:
+ app: zabbix-postgres
+ ports:
+ - port: 5432
+ targetPort: 5432
+ name: postgres
+ clusterIP: None
+---
+# Zabbix Server
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: zabbix-server
+ namespace: zabbix
+ labels:
+ app: zabbix-server
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: zabbix-server
+ template:
+ metadata:
+ labels:
+ app: zabbix-server
+ spec:
+ containers:
+ - name: zabbix-server
+ image: zabbix/zabbix-server-pgsql:7.2-alpine-latest
+ ports:
+ - containerPort: 10051
+ name: trapper
+ env:
+ - name: DB_SERVER_HOST
+ value: zabbix-postgres
+ - name: DB_SERVER_PORT
+ value: "5432"
+ - name: POSTGRES_USER
+ valueFrom:
+ secretKeyRef:
+ name: zabbix-db-secret
+ key: POSTGRES_USER
+ - name: POSTGRES_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: zabbix-db-secret
+ key: POSTGRES_PASSWORD
+ - name: POSTGRES_DB
+ valueFrom:
+ secretKeyRef:
+ name: zabbix-db-secret
+ key: POSTGRES_DB
+ resources:
+ requests:
+ memory: 256Mi
+ cpu: 100m
+ limits:
+ memory: 1Gi
+ cpu: "1"
+ livenessProbe:
+ tcpSocket:
+ port: 10051
+ initialDelaySeconds: 60
+ periodSeconds: 10
+ readinessProbe:
+ tcpSocket:
+ port: 10051
+ initialDelaySeconds: 30
+ periodSeconds: 5
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: zabbix-server
+ namespace: zabbix
+spec:
+ selector:
+ app: zabbix-server
+ ports:
+ - port: 10051
+ targetPort: 10051
+ name: trapper
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: zabbix-trapper
+ namespace: zabbix
+ annotations:
+ metallb.universe.tf/loadBalancerIPs: 10.0.56.203
+spec:
+ type: LoadBalancer
+ selector:
+ app: zabbix-server
+ ports:
+ - port: 10051
+ targetPort: 10051
+ name: trapper
+ protocol: TCP
+---
+# Zabbix Web (nginx + PostgreSQL)
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: zabbix-web
+ namespace: zabbix
+ labels:
+ app: zabbix-web
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: zabbix-web
+ template:
+ metadata:
+ labels:
+ app: zabbix-web
+ spec:
+ containers:
+ - name: zabbix-web
+ image: zabbix/zabbix-web-nginx-pgsql:7.2-alpine-latest
+ ports:
+ - containerPort: 8080
+ name: http
+ env:
+ - name: ZBX_SERVER_HOST
+ value: zabbix-server
+ - name: ZBX_SERVER_NAME
+ value: "BlueJay NOC"
+ - name: PHP_TZ
+ value: America/Chicago
+ - name: DB_SERVER_HOST
+ value: zabbix-postgres
+ - name: DB_SERVER_PORT
+ value: "5432"
+ - name: POSTGRES_USER
+ valueFrom:
+ secretKeyRef:
+ name: zabbix-db-secret
+ key: POSTGRES_USER
+ - name: POSTGRES_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: zabbix-db-secret
+ key: POSTGRES_PASSWORD
+ - name: POSTGRES_DB
+ valueFrom:
+ secretKeyRef:
+ name: zabbix-db-secret
+ key: POSTGRES_DB
+ - name: ZBX_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: zabbix-admin-secret
+ key: ZBX_ADMIN_PASSWORD
+ resources:
+ requests:
+ memory: 128Mi
+ cpu: 50m
+ limits:
+ memory: 512Mi
+ cpu: 500m
+ livenessProbe:
+ httpGet:
+ path: /
+ port: 8080
+ initialDelaySeconds: 60
+ periodSeconds: 10
+ readinessProbe:
+ httpGet:
+ path: /
+ port: 8080
+ initialDelaySeconds: 30
+ periodSeconds: 5
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: zabbix-web
+ namespace: zabbix
+spec:
+ selector:
+ app: zabbix-web
+ ports:
+ - port: 8080
+ targetPort: 8080
+ name: http
+---
+# TLS Certificate via cert-manager
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+ name: zabbix-tls
+ namespace: zabbix
+spec:
+ secretName: zabbix-tls
+ issuerRef:
+ name: step-ca-acme
+ kind: ClusterIssuer
+ dnsNames:
+ - zabbix.iamworkin.lan
+---
+# Traefik IngressRoute
+apiVersion: traefik.io/v1alpha1
+kind: IngressRoute
+metadata:
+ name: zabbix-web
+ namespace: zabbix
+spec:
+ entryPoints:
+ - websecure
+ routes:
+ - match: Host(`zabbix.iamworkin.lan`)
+ kind: Rule
+ services:
+ - name: zabbix-web
+ port: 8080
+ tls:
+ secretName: zabbix-tls