feat(neuron): add stage and prod k8s manifests + Argo CD apps

Completes the three-env setup (dev was added previously). Each env has
deployments, services, ingress, PVC, ConfigMap, and ExternalSecret pulling
from Vault. Prod has larger resource limits and 10Gi PVC. Vault secret at
secret/neuron-technologies/prod seeded separately.
This commit is contained in:
Will Anderson
2026-04-17 09:43:23 -05:00
parent 912e129e0d
commit 1b8ea63541
18 changed files with 517 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: neuron-prod
namespace: argocd
spec:
project: default
source:
repoURL: http://10.43.1.53:3000/will/infrastructure.git
targetRevision: main
path: servers/legion/k8s/neuron-technologies/prod
destination:
server: https://kubernetes.default.svc
namespace: neuron-prod
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=false
+20
View File
@@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: neuron-stage
namespace: argocd
spec:
project: default
source:
repoURL: http://10.43.1.53:3000/will/infrastructure.git
targetRevision: main
path: servers/legion/k8s/neuron-technologies/stage
destination:
server: https://kubernetes.default.svc
namespace: neuron-stage
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=false
@@ -0,0 +1,12 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: neuron-prod-config
namespace: neuron-prod
data:
SPRING_PROFILES_ACTIVE: "prod"
NEURON_DB_PATH: "/data/neuron-prod.db"
NEURON_STORAGE_PATH: "/data"
SERVER_TOMCAT_ACCESSLOG_ENABLED: "true"
MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: "health,info,metrics"
MANAGEMENT_ENDPOINT_HEALTH_SHOW_DETAILS: "always"
@@ -0,0 +1,18 @@
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: neuron-prod-secrets
namespace: neuron-prod
spec:
refreshInterval: 1h
secretStoreRef:
name: vault
kind: ClusterSecretStore
target:
name: neuron-prod-secrets
creationPolicy: Owner
data:
- secretKey: NEURON_WEBHOOK_SECRET
remoteRef:
key: secret/data/neuron-technologies/prod
property: gitea_webhook_secret
@@ -0,0 +1,43 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: neuron-prod
namespace: neuron-prod
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: traefik
tls:
- secretName: neuron-prod-tls
hosts:
- neurontechnologies.ai
- www.neurontechnologies.ai
rules:
- host: neurontechnologies.ai
http:
paths:
- path: /mcp
pathType: Prefix
backend:
service:
name: neuron-mcp
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: neuron-rest
port:
number: 8081
- host: www.neurontechnologies.ai
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: neuron-rest
port:
number: 8081
@@ -0,0 +1,10 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- configmap.yaml
- pvc.yaml
- externalsecret.yaml
- mcp-deployment.yaml
- rest-deployment.yaml
- services.yaml
- ingress.yaml
@@ -0,0 +1,59 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: neuron-mcp
namespace: neuron-prod
labels:
app: neuron-mcp
env: prod
spec:
replicas: 1
selector:
matchLabels:
app: neuron-mcp
template:
metadata:
labels:
app: neuron-mcp
env: prod
spec:
containers:
- name: neuron-mcp
image: registry.neuralplatform.ai/neuron-technologies/neuron-mcp:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 8080
envFrom:
- configMapRef:
name: neuron-prod-config
- secretRef:
name: neuron-prod-secrets
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: http
initialDelaySeconds: 30
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: http
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
volumes:
- name: data
persistentVolumeClaim:
claimName: neuron-prod-data
@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: neuron-prod-data
namespace: neuron-prod
spec:
storageClassName: local-path
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
@@ -0,0 +1,59 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: neuron-rest
namespace: neuron-prod
labels:
app: neuron-rest
env: prod
spec:
replicas: 1
selector:
matchLabels:
app: neuron-rest
template:
metadata:
labels:
app: neuron-rest
env: prod
spec:
containers:
- name: neuron-rest
image: registry.neuralplatform.ai/neuron-technologies/neuron-rest:latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 8081
envFrom:
- configMapRef:
name: neuron-prod-config
- secretRef:
name: neuron-prod-secrets
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: http
initialDelaySeconds: 30
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: http
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
volumes:
- name: data
persistentVolumeClaim:
claimName: neuron-prod-data
@@ -0,0 +1,31 @@
apiVersion: v1
kind: Service
metadata:
name: neuron-mcp
namespace: neuron-prod
labels:
app: neuron-mcp
spec:
selector:
app: neuron-mcp
ports:
- name: http
port: 8080
targetPort: 8080
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: neuron-rest
namespace: neuron-prod
labels:
app: neuron-rest
spec:
selector:
app: neuron-rest
ports:
- name: http
port: 8081
targetPort: 8081
type: ClusterIP
@@ -0,0 +1,12 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: neuron-stage-config
namespace: neuron-stage
data:
SPRING_PROFILES_ACTIVE: "stage"
NEURON_DB_PATH: "/data/neuron-stage.db"
NEURON_STORAGE_PATH: "/data"
SERVER_TOMCAT_ACCESSLOG_ENABLED: "true"
MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: "health,info,metrics"
MANAGEMENT_ENDPOINT_HEALTH_SHOW_DETAILS: "always"
@@ -0,0 +1,18 @@
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: neuron-stage-secrets
namespace: neuron-stage
spec:
refreshInterval: 1h
secretStoreRef:
name: vault
kind: ClusterSecretStore
target:
name: neuron-stage-secrets
creationPolicy: Owner
data:
- secretKey: NEURON_WEBHOOK_SECRET
remoteRef:
key: secret/data/neuron-technologies/stage
property: gitea_webhook_secret
@@ -0,0 +1,32 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: neuron-stage
namespace: neuron-stage
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: traefik
tls:
- secretName: neuron-stage-tls
hosts:
- stage.neurontechnologies.ai
rules:
- host: stage.neurontechnologies.ai
http:
paths:
- path: /mcp
pathType: Prefix
backend:
service:
name: neuron-mcp
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: neuron-rest
port:
number: 8081
@@ -0,0 +1,10 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- configmap.yaml
- pvc.yaml
- externalsecret.yaml
- mcp-deployment.yaml
- rest-deployment.yaml
- services.yaml
- ingress.yaml
@@ -0,0 +1,59 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: neuron-mcp
namespace: neuron-stage
labels:
app: neuron-mcp
env: stage
spec:
replicas: 1
selector:
matchLabels:
app: neuron-mcp
template:
metadata:
labels:
app: neuron-mcp
env: stage
spec:
containers:
- name: neuron-mcp
image: registry.neuralplatform.ai/neuron-technologies/neuron-mcp:stage-latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 8080
envFrom:
- configMapRef:
name: neuron-stage-config
- secretRef:
name: neuron-stage-secrets
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 100m
memory: 384Mi
limits:
cpu: 500m
memory: 768Mi
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: http
initialDelaySeconds: 30
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: http
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
volumes:
- name: data
persistentVolumeClaim:
claimName: neuron-stage-data
@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: neuron-stage-data
namespace: neuron-stage
spec:
storageClassName: local-path
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
@@ -0,0 +1,59 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: neuron-rest
namespace: neuron-stage
labels:
app: neuron-rest
env: stage
spec:
replicas: 1
selector:
matchLabels:
app: neuron-rest
template:
metadata:
labels:
app: neuron-rest
env: stage
spec:
containers:
- name: neuron-rest
image: registry.neuralplatform.ai/neuron-technologies/neuron-rest:stage-latest
imagePullPolicy: Always
ports:
- name: http
containerPort: 8081
envFrom:
- configMapRef:
name: neuron-stage-config
- secretRef:
name: neuron-stage-secrets
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 100m
memory: 384Mi
limits:
cpu: 500m
memory: 768Mi
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: http
initialDelaySeconds: 30
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: http
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3
volumes:
- name: data
persistentVolumeClaim:
claimName: neuron-stage-data
@@ -0,0 +1,31 @@
apiVersion: v1
kind: Service
metadata:
name: neuron-mcp
namespace: neuron-stage
labels:
app: neuron-mcp
spec:
selector:
app: neuron-mcp
ports:
- name: http
port: 8080
targetPort: 8080
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: neuron-rest
namespace: neuron-stage
labels:
app: neuron-rest
spec:
selector:
app: neuron-rest
ports:
- name: http
port: 8081
targetPort: 8081
type: ClusterIP