Files
momentum-system/deploy/helm/momentum/templates/cronjobs.yaml
T
Claude e91979a622 Add Kubernetes image + Helm package with in-cluster Postgres
Containerizes the momentum monolith and packages every run mode for
deployment in a single Kubernetes namespace, with PostgreSQL hosted in
the cluster.

- Dockerfile (python:3.11-slim, non-root, writable /app/data) + .dockerignore
- GitHub Actions workflow publishing to ghcr.io/fez5587/momentum-system
- Helm chart (deploy/helm/momentum):
  * PostgreSQL StatefulSet + PVC (single source of truth; schema
    auto-creates from storage/pg_schema.sql on first connect)
  * App Deployment running run_live_paper.py with the embedded dashboard
    (replicas: 1, Recreate; the dashboard's write endpoints need the
    in-process TradingExecutionService) + Service/Ingress on 8010, plus a
    wait-for-postgres initContainer
  * CronJobs for journal / eod-replay / nightly-tune (US/Eastern via
    spec.timeZone) sharing the app data PVC
  * ConfigMap (tuning env) + Secret (DATABASE_URL/broker keys, existingSecret
    supported); DATABASE_URL built from the in-cluster Postgres service
  * Optional Grafana provisioned against the in-cluster Postgres
- deploy/README.md with install, secrets, and constraints

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JCVMm2AbmZvvxwLTX6UpNR
2026-06-19 17:22:06 +00:00

60 lines
2.2 KiB
YAML

{{- if .Values.cronjobs.enabled }}
{{- $root := . }}
{{- $jobs := dict "journal" .Values.cronjobs.journal "eod-replay" .Values.cronjobs.eodReplay "nightly-tune" .Values.cronjobs.nightlyTune }}
{{- range $key, $job := $jobs }}
{{- if $job.enabled }}
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: {{ include "momentum.fullname" $root }}-{{ $key }}
labels:
{{- include "momentum.labels" $root | nindent 4 }}
app.kubernetes.io/component: cron-{{ $key }}
spec:
schedule: {{ $job.schedule | quote }}
# US/Eastern so the market-clock schedules in .env's *.sh comments hold.
timeZone: {{ $root.Values.cronjobs.timeZone | quote }}
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 3
jobTemplate:
spec:
backoffLimit: 1
template:
metadata:
labels:
{{- include "momentum.selectorLabels" (dict "ctx" $root "component" (printf "cron-%s" $key)) | nindent 12 }}
spec:
restartPolicy: Never
{{- with $root.Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 12 }}
{{- end }}
containers:
- name: {{ $key }}
image: "{{ $root.Values.image.repository }}:{{ $root.Values.image.tag }}"
imagePullPolicy: {{ $root.Values.image.pullPolicy }}
command: {{ toYaml $job.command | nindent 16 }}
envFrom:
- configMapRef:
name: {{ include "momentum.configMapName" $root }}
- secretRef:
name: {{ include "momentum.secretName" $root }}
volumeMounts:
- name: app-data
mountPath: /app/data
volumes:
- name: app-data
{{- if $root.Values.app.persistence.enabled }}
# Shared with the app pod (nightly-tune writes learned_params.json
# the loop reads on boot). RWO ⇒ cron pods schedule onto the app's node.
persistentVolumeClaim:
claimName: {{ include "momentum.appDataPvcName" $root }}
{{- else }}
emptyDir: {}
{{- end }}
{{- end }}
{{- end }}
{{- end }}