feat: add harmonic-wordpress dev environment on Legion

- Add harmonic-wordpress namespace
- WordPress + MySQL deployment with PVCs and ExternalSecrets
- Ingress for dev.harmonic-framework.com via Traefik + cert-manager
- Argo CD Application watching k8s/harmonic-wordpress/
- Add public Gitea repo credential for git.neuralplatform.ai
This commit is contained in:
Will Anderson
2026-04-04 09:47:41 -05:00
parent fb0284d72a
commit 6a9db2094e
7 changed files with 273 additions and 1 deletions
@@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: harmonic-wordpress
namespace: argocd
spec:
project: default
source:
repoURL: https://git.neuralplatform.ai/will/infrastructure.git
targetRevision: main
path: servers/legion/k8s/harmonic-wordpress
destination:
server: https://kubernetes.default.svc
namespace: harmonic-wordpress
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
+21 -1
View File
@@ -83,7 +83,7 @@ resource "kubernetes_ingress_v1" "argocd" {
depends_on = [helm_release.argocd, helm_release.cert_manager]
}
# Gitea repo credentials for Argo CD
# Gitea repo credentials for Argo CD (internal cluster IP)
# Label argocd.argoproj.io/secret-type=repository tells Argo CD to use this as a repo credential
resource "kubernetes_secret" "argocd_gitea_repo" {
metadata {
@@ -104,6 +104,26 @@ resource "kubernetes_secret" "argocd_gitea_repo" {
depends_on = [helm_release.argocd]
}
# Gitea repo credentials via public hostname (for apps referencing git.neuralplatform.ai)
resource "kubernetes_secret" "argocd_gitea_repo_public" {
metadata {
name = "argocd-repo-gitea-infrastructure-public"
namespace = kubernetes_namespace.argocd.metadata[0].name
labels = {
"argocd.argoproj.io/secret-type" = "repository"
}
}
data = {
type = "git"
url = "https://git.neuralplatform.ai/will/infrastructure.git"
username = "will"
password = var.gitea_api_token
}
depends_on = [helm_release.argocd]
}
# Root application — watches servers/legion/apps/ for app manifests
resource "kubernetes_manifest" "argocd_root_app" {
manifest = {
@@ -0,0 +1,150 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
namespace: harmonic-wordpress
labels:
app: mysql
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
env:
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wordpress
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: wordpress-db
key: mysql_password
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: wordpress-db
key: mysql_root_password
volumeMounts:
- name: data
mountPath: /var/lib/mysql
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 512Mi
cpu: 500m
livenessProbe:
exec:
command: ["mysqladmin", "ping", "-h", "localhost"]
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command: ["mysqladmin", "ping", "-h", "localhost"]
initialDelaySeconds: 10
periodSeconds: 5
volumes:
- name: data
persistentVolumeClaim:
claimName: mysql-data
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: harmonic-wordpress
spec:
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
namespace: harmonic-wordpress
labels:
app: wordpress
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress:latest
ports:
- containerPort: 80
env:
- name: WORDPRESS_DB_HOST
value: mysql:3306
- name: WORDPRESS_DB_NAME
value: wordpress
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: wordpress-db
key: mysql_password
- name: WORDPRESS_CONFIG_EXTRA
value: |
define('WP_HOME', 'https://dev.harmonic-framework.com');
define('WP_SITEURL', 'https://dev.harmonic-framework.com');
volumeMounts:
- name: data
mountPath: /var/www/html
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 512Mi
cpu: 500m
readinessProbe:
httpGet:
path: /wp-login.php
port: 80
initialDelaySeconds: 30
periodSeconds: 10
volumes:
- name: data
persistentVolumeClaim:
claimName: wordpress-data
---
apiVersion: v1
kind: Service
metadata:
name: wordpress
namespace: harmonic-wordpress
spec:
selector:
app: wordpress
ports:
- port: 80
targetPort: 80
type: ClusterIP
@@ -0,0 +1,22 @@
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: wordpress-db
namespace: harmonic-wordpress
spec:
refreshInterval: 1h
secretStoreRef:
name: vault
kind: ClusterSecretStore
target:
name: wordpress-db
creationPolicy: Owner
data:
- secretKey: mysql_root_password
remoteRef:
key: secret/data/harmonic-wordpress
property: mysql_root_password
- secretKey: mysql_password
remoteRef:
key: secret/data/harmonic-wordpress
property: mysql_password
@@ -0,0 +1,25 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wordpress
namespace: harmonic-wordpress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: traefik
tls:
- hosts:
- dev.harmonic-framework.com
secretName: wordpress-tls
rules:
- host: dev.harmonic-framework.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: wordpress
port:
number: 80
@@ -0,0 +1,25 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wordpress-data
namespace: harmonic-wordpress
spec:
storageClassName: local-path
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-data
namespace: harmonic-wordpress
spec:
storageClassName: local-path
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
+10
View File
@@ -37,3 +37,13 @@ resource "kubernetes_namespace" "mudcraft" {
}
}
}
resource "kubernetes_namespace" "harmonic_wordpress" {
metadata {
name = "harmonic-wordpress"
labels = {
managed-by = "terraform"
tier = "apps"
}
}
}