Add Helm chart and GitLab CI pipeline

- Helm chart with PostgreSQL, MinIO, Redis as optional subcharts
- Production and external infrastructure value files
- HPA, Ingress, and health probe support
- GitLab CI pipeline using Buildah for container builds
- Multi-stage pipeline: test, build, publish
This commit is contained in:
Mondo Diaz
2025-12-04 14:57:46 -06:00
parent a0e350ee7f
commit cd75cb864d
16 changed files with 926 additions and 0 deletions

92
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,92 @@
stages:
- test
- build
- publish
variables:
# Container registry settings
REGISTRY: ${CI_REGISTRY}
IMAGE_NAME: ${CI_REGISTRY_IMAGE}
# Buildah settings
STORAGE_DRIVER: vfs
BUILDAH_FORMAT: docker
BUILDAH_ISOLATION: chroot
.buildah-base:
image: quay.io/buildah/stable:latest
before_script:
- buildah version
- buildah login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}
# Run Go tests
test:
stage: test
image: golang:1.22-alpine
before_script:
- apk add --no-cache git
script:
- go mod download
- go vet ./...
- go test -v -race ./...
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
# Build container image for merge requests (no push)
build:
stage: build
extends: .buildah-base
script:
- |
buildah build \
--tag ${IMAGE_NAME}:${CI_COMMIT_SHORT_SHA} \
--label org.opencontainers.image.source=${CI_PROJECT_URL} \
--label org.opencontainers.image.revision=${CI_COMMIT_SHA} \
--label org.opencontainers.image.created=$(date -u +%Y-%m-%dT%H:%M:%SZ) \
--layers \
--cache-from ${IMAGE_NAME}:latest \
.
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# Build and push on main branch
publish:
stage: publish
extends: .buildah-base
script:
- |
buildah build \
--tag ${IMAGE_NAME}:${CI_COMMIT_SHORT_SHA} \
--tag ${IMAGE_NAME}:${CI_COMMIT_REF_SLUG} \
--tag ${IMAGE_NAME}:latest \
--label org.opencontainers.image.source=${CI_PROJECT_URL} \
--label org.opencontainers.image.revision=${CI_COMMIT_SHA} \
--label org.opencontainers.image.created=$(date -u +%Y-%m-%dT%H:%M:%SZ) \
--layers \
--cache-from ${IMAGE_NAME}:latest \
.
- buildah push ${IMAGE_NAME}:${CI_COMMIT_SHORT_SHA}
- buildah push ${IMAGE_NAME}:${CI_COMMIT_REF_SLUG}
- buildah push ${IMAGE_NAME}:latest
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
# Build and push tagged releases
publish-release:
stage: publish
extends: .buildah-base
script:
- |
buildah build \
--tag ${IMAGE_NAME}:${CI_COMMIT_TAG} \
--tag ${IMAGE_NAME}:latest \
--label org.opencontainers.image.source=${CI_PROJECT_URL} \
--label org.opencontainers.image.revision=${CI_COMMIT_SHA} \
--label org.opencontainers.image.version=${CI_COMMIT_TAG} \
--label org.opencontainers.image.created=$(date -u +%Y-%m-%dT%H:%M:%SZ) \
--layers \
.
- buildah push ${IMAGE_NAME}:${CI_COMMIT_TAG}
- buildah push ${IMAGE_NAME}:latest
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/

18
helm/orchard/.helmignore Normal file
View File

@@ -0,0 +1,18 @@
# Patterns to ignore when building packages.
.DS_Store
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
*.swp
*.bak
*.tmp
*.orig
*~
.project
.idea/
*.tmproj
.vscode/

29
helm/orchard/Chart.yaml Normal file
View File

@@ -0,0 +1,29 @@
apiVersion: v2
name: orchard
description: Content-Addressable Storage System for binary artifacts
type: application
version: 0.1.0
appVersion: "1.0.0"
keywords:
- artifact-storage
- content-addressable
- binary-storage
- package-registry
home: https://git.bitstorm.ca/bitforge/orchard
sources:
- https://git.bitstorm.ca/bitforge/orchard
maintainers:
- name: BitForge
dependencies:
- name: postgresql
version: "15.5.x"
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled
- name: minio
version: "14.x.x"
repository: https://charts.bitnami.com/bitnami
condition: minio.enabled
- name: redis
version: "19.x.x"
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled

View File

@@ -0,0 +1,66 @@
Orchard has been installed!
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "orchard.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "orchard.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "orchard.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "orchard.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}
2. API Endpoints:
- Health Check: GET /health
- List Groves: GET /api/v1/groves
- Create Grove: POST /api/v1/groves
- Upload: POST /api/v1/grove/{grove}/{tree}/cultivate
- Download: GET /api/v1/grove/{grove}/{tree}/+/{ref}
3. Example Usage:
# Create a grove
curl -X POST http://localhost:8080/api/v1/groves \
-H "Content-Type: application/json" \
-d '{"name": "my-project", "description": "My project", "is_public": true}'
# Create a tree
curl -X POST http://localhost:8080/api/v1/grove/my-project/trees \
-H "Content-Type: application/json" \
-d '{"name": "releases", "description": "Release builds"}'
# Upload an artifact
curl -X POST http://localhost:8080/api/v1/grove/my-project/releases/cultivate \
-F "file=@./my-artifact.tar.gz" \
-F "tag=v1.0.0"
# Download an artifact
curl -O http://localhost:8080/api/v1/grove/my-project/releases/+/v1.0.0
{{- if .Values.postgresql.enabled }}
4. PostgreSQL is deployed as a subchart.
Connection: {{ include "orchard.postgresql.host" . }}:5432
{{- end }}
{{- if .Values.minio.enabled }}
5. MinIO is deployed as a subchart.
Endpoint: {{ include "orchard.minio.host" . }}
Bucket: {{ .Values.orchard.s3.bucket }}
{{- end }}
For more information, visit: https://git.bitstorm.ca/bitforge/orchard

View File

@@ -0,0 +1,121 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "orchard.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
*/}}
{{- define "orchard.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "orchard.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "orchard.labels" -}}
helm.sh/chart: {{ include "orchard.chart" . }}
{{ include "orchard.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "orchard.selectorLabels" -}}
app.kubernetes.io/name: {{ include "orchard.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "orchard.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "orchard.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
PostgreSQL host
*/}}
{{- define "orchard.postgresql.host" -}}
{{- if .Values.postgresql.enabled }}
{{- printf "%s-postgresql" .Release.Name }}
{{- else }}
{{- .Values.orchard.database.host }}
{{- end }}
{{- end }}
{{/*
PostgreSQL secret name
*/}}
{{- define "orchard.postgresql.secretName" -}}
{{- if .Values.orchard.database.existingSecret }}
{{- .Values.orchard.database.existingSecret }}
{{- else if .Values.postgresql.enabled }}
{{- printf "%s-postgresql" .Release.Name }}
{{- else }}
{{- printf "%s-db-secret" (include "orchard.fullname" .) }}
{{- end }}
{{- end }}
{{/*
PostgreSQL password key in secret
*/}}
{{- define "orchard.postgresql.passwordKey" -}}
{{- if .Values.orchard.database.existingSecret }}
{{- .Values.orchard.database.existingSecretPasswordKey }}
{{- else if .Values.postgresql.enabled }}
password
{{- else }}
password
{{- end }}
{{- end }}
{{/*
MinIO host
*/}}
{{- define "orchard.minio.host" -}}
{{- if .Values.minio.enabled }}
{{- printf "http://%s-minio:9000" .Release.Name }}
{{- else }}
{{- .Values.orchard.s3.endpoint }}
{{- end }}
{{- end }}
{{/*
MinIO secret name
*/}}
{{- define "orchard.minio.secretName" -}}
{{- if .Values.orchard.s3.existingSecret }}
{{- .Values.orchard.s3.existingSecret }}
{{- else if .Values.minio.enabled }}
{{- printf "%s-minio" .Release.Name }}
{{- else }}
{{- printf "%s-s3-secret" (include "orchard.fullname" .) }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,22 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "orchard.fullname" . }}-config
labels:
{{- include "orchard.labels" . | nindent 4 }}
data:
config.yaml: |
server:
host: {{ .Values.orchard.server.host | quote }}
port: {{ .Values.orchard.server.port }}
database:
host: {{ include "orchard.postgresql.host" . | quote }}
port: {{ .Values.orchard.database.port }}
user: {{ .Values.orchard.database.user | default .Values.postgresql.auth.username | quote }}
dbname: {{ .Values.orchard.database.dbname | default .Values.postgresql.auth.database | quote }}
sslmode: {{ .Values.orchard.database.sslmode | quote }}
s3:
endpoint: {{ include "orchard.minio.host" . | quote }}
region: {{ .Values.orchard.s3.region | quote }}
bucket: {{ .Values.orchard.s3.bucket | quote }}
use_path_style: {{ .Values.orchard.s3.usePathStyle }}

View File

@@ -0,0 +1,111 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "orchard.fullname" . }}
labels:
{{- include "orchard.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "orchard.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "orchard.labels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "orchard.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
initContainers:
{{- if .Values.migrations.enabled }}
- name: wait-for-db
image: busybox:1.36
command: ['sh', '-c', 'until nc -z {{ include "orchard.postgresql.host" . }} 5432; do echo waiting for database; sleep 2; done;']
{{- end }}
{{- if .Values.minio.enabled }}
- name: wait-for-minio
image: busybox:1.36
command: ['sh', '-c', 'until nc -z {{ .Release.Name }}-minio 9000; do echo waiting for minio; sleep 2; done;']
{{- end }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.orchard.server.port }}
protocol: TCP
env:
- name: ORCHARD_SERVER_HOST
value: {{ .Values.orchard.server.host | quote }}
- name: ORCHARD_SERVER_PORT
value: {{ .Values.orchard.server.port | quote }}
- name: ORCHARD_DATABASE_HOST
value: {{ include "orchard.postgresql.host" . | quote }}
- name: ORCHARD_DATABASE_PORT
value: {{ .Values.orchard.database.port | quote }}
- name: ORCHARD_DATABASE_USER
value: {{ .Values.orchard.database.user | default .Values.postgresql.auth.username | quote }}
- name: ORCHARD_DATABASE_DBNAME
value: {{ .Values.orchard.database.dbname | default .Values.postgresql.auth.database | quote }}
- name: ORCHARD_DATABASE_SSLMODE
value: {{ .Values.orchard.database.sslmode | quote }}
- name: ORCHARD_DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "orchard.postgresql.secretName" . }}
key: {{ include "orchard.postgresql.passwordKey" . }}
- name: ORCHARD_S3_ENDPOINT
value: {{ include "orchard.minio.host" . | quote }}
- name: ORCHARD_S3_REGION
value: {{ .Values.orchard.s3.region | quote }}
- name: ORCHARD_S3_BUCKET
value: {{ .Values.orchard.s3.bucket | quote }}
- name: ORCHARD_S3_USE_PATH_STYLE
value: {{ .Values.orchard.s3.usePathStyle | quote }}
- name: ORCHARD_S3_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: {{ include "orchard.minio.secretName" . }}
key: {{ if .Values.minio.enabled }}root-user{{ else }}{{ .Values.orchard.s3.existingSecretAccessKeyKey }}{{ end }}
- name: ORCHARD_S3_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: {{ include "orchard.minio.secretName" . }}
key: {{ if .Values.minio.enabled }}root-password{{ else }}{{ .Values.orchard.s3.existingSecretSecretKeyKey }}{{ end }}
livenessProbe:
{{- toYaml .Values.livenessProbe | nindent 12 }}
readinessProbe:
{{- toYaml .Values.readinessProbe | nindent 12 }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@@ -0,0 +1,32 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "orchard.fullname" . }}
labels:
{{- include "orchard.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "orchard.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,41 @@
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "orchard.fullname" . }}
labels:
{{- include "orchard.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ include "orchard.fullname" $ }}
port:
name: http
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,51 @@
{{- if .Values.migrations.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "orchard.fullname" . }}-migrations
labels:
{{- include "orchard.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
template:
metadata:
labels:
{{- include "orchard.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
restartPolicy: Never
initContainers:
- name: wait-for-db
image: busybox:1.36
command: ['sh', '-c', 'until nc -z {{ include "orchard.postgresql.host" . }} 5432; do echo waiting for database; sleep 2; done;']
containers:
- name: migrations
image: "{{ .Values.migrations.image.repository }}:{{ .Values.migrations.image.tag | default .Chart.AppVersion }}"
command: ["/bin/sh", "-c"]
args:
- |
# The orchard-server automatically runs migrations on startup
# This job just verifies connectivity
echo "Database is ready at {{ include "orchard.postgresql.host" . }}:5432"
env:
- name: ORCHARD_DATABASE_HOST
value: {{ include "orchard.postgresql.host" . | quote }}
- name: ORCHARD_DATABASE_PORT
value: {{ .Values.orchard.database.port | quote }}
- name: ORCHARD_DATABASE_USER
value: {{ .Values.orchard.database.user | default .Values.postgresql.auth.username | quote }}
- name: ORCHARD_DATABASE_DBNAME
value: {{ .Values.orchard.database.dbname | default .Values.postgresql.auth.database | quote }}
- name: ORCHARD_DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "orchard.postgresql.secretName" . }}
key: {{ include "orchard.postgresql.passwordKey" . }}
backoffLimit: 3
{{- end }}

View File

@@ -0,0 +1,24 @@
{{- if and (not .Values.postgresql.enabled) (not .Values.orchard.database.existingSecret) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "orchard.fullname" . }}-db-secret
labels:
{{- include "orchard.labels" . | nindent 4 }}
type: Opaque
data:
password: {{ .Values.orchard.database.password | b64enc | quote }}
{{- end }}
---
{{- if and (not .Values.minio.enabled) (not .Values.orchard.s3.existingSecret) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "orchard.fullname" . }}-s3-secret
labels:
{{- include "orchard.labels" . | nindent 4 }}
type: Opaque
data:
access-key-id: {{ .Values.orchard.s3.accessKeyId | b64enc | quote }}
secret-access-key: {{ .Values.orchard.s3.secretAccessKey | b64enc | quote }}
{{- end }}

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "orchard.fullname" . }}
labels:
{{- include "orchard.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "orchard.selectorLabels" . | nindent 4 }}

View File

@@ -0,0 +1,13 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "orchard.serviceAccountName" . }}
labels:
{{- include "orchard.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
{{- end }}

View File

@@ -0,0 +1,58 @@
# Values for using external PostgreSQL and S3 storage
# Use this when you have existing infrastructure
replicaCount: 2
image:
pullPolicy: Always
# Disable subcharts - use external services
postgresql:
enabled: false
minio:
enabled: false
redis:
enabled: false
orchard:
database:
host: "your-postgres-host.example.com"
port: 5432
user: orchard
dbname: orchard
sslmode: require
# Option 1: Use existing secret
existingSecret: "my-postgres-secret"
existingSecretPasswordKey: "password"
# Option 2: Set password directly (not recommended)
# password: "your-password"
s3:
endpoint: "https://s3.amazonaws.com"
region: us-east-1
bucket: orchard-artifacts
usePathStyle: false
# Option 1: Use existing secret
existingSecret: "my-s3-secret"
existingSecretAccessKeyKey: "access-key-id"
existingSecretSecretKeyKey: "secret-access-key"
# Option 2: Set credentials directly (not recommended)
# accessKeyId: "your-access-key"
# secretAccessKey: "your-secret-key"
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: orchard.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: orchard-tls
hosts:
- orchard.example.com

View File

@@ -0,0 +1,80 @@
# Production values for orchard
replicaCount: 3
image:
pullPolicy: Always
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 250m
memory: 256Mi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 20
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/proxy-body-size: "500m"
hosts:
- host: orchard.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: orchard-tls
hosts:
- orchard.example.com
orchard:
database:
sslmode: require
postgresql:
enabled: true
auth:
password: "" # Set via --set or external secret
primary:
persistence:
enabled: true
size: 100Gi
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 500m
memory: 1Gi
minio:
enabled: true
auth:
rootPassword: "" # Set via --set or external secret
persistence:
enabled: true
size: 500Gi
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 500m
memory: 1Gi
redis:
enabled: true
auth:
password: "" # Set via --set or external secret
master:
persistence:
enabled: true
size: 10Gi

153
helm/orchard/values.yaml Normal file
View File

@@ -0,0 +1,153 @@
# Default values for orchard
replicaCount: 1
image:
repository: orchard-server
pullPolicy: IfNotPresent
tag: "" # Defaults to chart appVersion
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
create: true
automount: true
annotations: {}
name: ""
podAnnotations: {}
podLabels: {}
podSecurityContext: {}
securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
service:
type: ClusterIP
port: 8080
ingress:
enabled: false
className: ""
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: orchard.local
paths:
- path: /
pathType: Prefix
tls: []
# - secretName: orchard-tls
# hosts:
# - orchard.local
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 5
periodSeconds: 5
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 80
targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
# Orchard server configuration
orchard:
server:
host: "0.0.0.0"
port: 8080
# Database configuration (used when postgresql.enabled is false)
database:
host: ""
port: 5432
user: orchard
password: ""
dbname: orchard
sslmode: disable
existingSecret: ""
existingSecretPasswordKey: "password"
# S3 configuration (used when minio.enabled is false)
s3:
endpoint: ""
region: us-east-1
bucket: orchard-artifacts
accessKeyId: ""
secretAccessKey: ""
usePathStyle: true
existingSecret: ""
existingSecretAccessKeyKey: "access-key-id"
existingSecretSecretKeyKey: "secret-access-key"
# PostgreSQL subchart configuration
postgresql:
enabled: true
auth:
username: orchard
password: orchard-password
database: orchard
primary:
persistence:
enabled: true
size: 10Gi
# MinIO subchart configuration
minio:
enabled: true
auth:
rootUser: minioadmin
rootPassword: minioadmin
defaultBuckets: "orchard-artifacts"
persistence:
enabled: true
size: 50Gi
# Redis subchart configuration (for future caching)
redis:
enabled: false
auth:
enabled: true
password: redis-password
architecture: standalone
master:
persistence:
enabled: true
size: 1Gi
# Database migrations
migrations:
enabled: true
image:
repository: orchard-server
tag: ""