Skip to main content

Helm Chart Reference

This guide provides a detailed reference for all configuration options available in the Gyre Helm chart.

Global Parameters

ParameterDescriptionDefault
nameOverrideOverride chart name""
fullnameOverrideOverride fully qualified app name""
originExplicit ORIGIN/BETTER_AUTH_URL value""
replicaCountNumber of replicas (SQLite requires 1)1

Image Configuration

ParameterDescriptionDefault
image.repositoryContainer image repositoryghcr.io/entropy0120/gyre
image.tagContainer image tag (overrides appVersion)""
image.pullPolicyImage pull policyIfNotPresent
imagePullSecretsImage pull secrets[]

Service Account

ParameterDescriptionDefault
serviceAccount.createCreate service accounttrue
serviceAccount.automountAutomount SA token for in-cluster Kubernetes authtrue
serviceAccount.annotationsSA annotations{}
serviceAccount.nameSA name (generated if empty)""

Service Configuration

ParameterDescriptionDefault
service.typeKubernetes service typeClusterIP
service.portService port80
service.targetPortContainer target port3000

Ingress Configuration

ParameterDescriptionDefault
ingress.enabledEnable ingressfalse
ingress.classNameIngress class name""
ingress.annotationsIngress annotations{}
ingress.hostsIngress hosts configurationSee values.yaml
ingress.tlsIngress TLS configuration[]

Gateway API Configuration

ParameterDescriptionDefault
gatewayApi.enabledEnable Gateway API HTTPRoute generationfalse
gatewayApi.parentRefsGateway parent references[]
gatewayApi.hostnamesHostnames used for HTTPRoute matching and ORIGIN derivation when origin is unsetSee values.yaml
gatewayApi.tlsTreat derived ORIGIN/BETTER_AUTH_URL as https:// when the Gateway terminates TLSfalse
gatewayApi.rulesOptional HTTPRoute rule overrides[]

Persistence

ParameterDescriptionDefault
persistence.enabledEnable persistent storagetrue
persistence.accessModePVC access modeReadWriteOnce
persistence.sizePVC size1Gi
persistence.storageClassStorage class name (blank = default)""
persistence.annotationsPVC annotations{}
persistence.existingClaimUse existing PVC""

Security Context

ParameterDescriptionDefault
podSecurityContext.runAsNonRootRun as non-roottrue
podSecurityContext.runAsUserUser ID1001
podSecurityContext.fsGroupFilesystem group1001
securityContext.allowPrivilegeEscalationAllow privilege escalationfalse
securityContext.capabilities.dropDrop capabilities["ALL"]
securityContext.readOnlyRootFilesystemRead-only root FStrue

Resource Limits

ParameterDescriptionDefault
resources.limits.cpuCPU limit500m
resources.limits.memoryMemory limit1Gi
resources.requests.cpuCPU request100m
resources.requests.memoryMemory request128Mi

Health Checks

ParameterDescriptionDefault
livenessProbe.initialDelaySecondsInitial delay30
livenessProbe.periodSecondsCheck period30
readinessProbe.initialDelaySecondsInitial delay10
readinessProbe.periodSecondsCheck period10

The default liveness probe uses /api/v1/health. The default readiness probe uses /api/v1/ready, which stays unavailable until Gyre initialization completes and remains unavailable after fatal startup failures.

RBAC

ParameterDescriptionDefault
rbac.createCreate RBAC resourcestrue
rbac.clusterRole.createCreate ClusterRoletrue
rbac.clusterRole.rulesAdditional RBAC rules[]

Admin Configuration

ParameterDescriptionDefault
admin.autoGenerateAuto-generate admin passwordtrue
admin.secretNameAdmin password secret namegyre-initial-admin-secret

Metrics & Monitoring

ParameterDescriptionDefault
metrics.enabledEnable application metricstrue
metrics.existingSecretSecret containing GYRE_METRICS_TOKEN""
metrics.serviceMonitor.enabledCreate a Prometheus ServiceMonitorfalse
metrics.serviceMonitor.intervalScraping interval30s
metrics.serviceMonitor.pathMetrics path/metrics
metrics.serviceMonitor.additionalLabelsAdditional labels for ServiceMonitor{}

Network Policy

ParameterDescriptionDefault
networkPolicy.enabledEnable NetworkPolicytrue
networkPolicy.apiServerNamespaceDeprecated fallback namespace name for Kubernetes API egress (e.g., default)default
networkPolicy.ingress.podSelectorPod selector for ingress rules{}
networkPolicy.ingress.namespaceSelectorNamespace selector for ingress rules{}
networkPolicy.ingress.additionalRulesAdditional ingress rules[]
networkPolicy.egress.apiServer.namespaceSelectorNamespace selector for Kubernetes API egress targets{}
networkPolicy.egress.apiServer.podSelectorOptional pod selector paired with the API-server namespace selector{}
networkPolicy.egress.apiServer.ipBlocksCIDRs for managed control-plane API endpoints[]
networkPolicy.egress.apiServer.portsAllowed TCP ports for Kubernetes API egress[443,6443]
networkPolicy.egress.additionalRulesAdditional egress rules[]

ORIGIN and BETTER_AUTH_URL resolve in this order:

  1. origin when non-empty
  2. The first enabled ingress host
  3. The first gatewayApi.hostnames entry, using gatewayApi.tls to choose http vs https
  4. The in-cluster service URL fallback

Application Configuration

ParameterDescriptionDefault
config.createCreate ConfigMap for app configurationtrue
config.pollIntervalMsKubernetes API polling interval (ms)5000
config.heartbeatIntervalMsSSE heartbeat interval (ms)30000
config.dashboardCacheTtlMsDashboard cache TTL (ms)30000
config.settlingPeriodMsSettling period for ADDED events (ms)30000
config.bodySizeLimitAdapter request-body ceiling (N, NK, NM, NG, or Infinity)500M
config.additionalConfigAdditional configuration key-value pairs{}

Helm config keys map to these runtime env vars:

Helm keyEnvironment variable
config.pollIntervalMsGYRE_POLL_INTERVAL_MS
config.heartbeatIntervalMsGYRE_HEARTBEAT_INTERVAL_MS
config.dashboardCacheTtlMsGYRE_DASHBOARD_CACHE_TTL_MS
config.settlingPeriodMsGYRE_SETTLING_PERIOD_MS
config.bodySizeLimitBODY_SIZE_LIMIT
config.additionalConfigPass-through key/value env vars

config.additionalConfig is rejected at render time when it contains chart-owned env vars. Reserved names include DATABASE_URL, NODE_ENV, ORIGIN, BODY_SIZE_LIMIT, polling/cache interval vars, encryption key vars, GYRE_METRICS_TOKEN, auth settings vars, GYRE_AUTH_PROVIDERS, and any GYRE_AUTH_PROVIDER_*_CLIENT_SECRET key. Use the matching chart value or secret setting instead.

Encryption Configuration

ParameterDescriptionDefault
encryption.gyreKeyKey for encrypting cluster kubeconfigs""
encryption.authKeyKey for encrypting OAuth client secrets""
encryption.backupKeyKey for encrypting backup files""
encryption.betterAuthSecretBetter Auth session signing secret""
encryption.existingSecretExisting secret with encryption keys""

encryption.existingSecret must include all of:

  • GYRE_ENCRYPTION_KEY
  • AUTH_ENCRYPTION_KEY
  • BACKUP_ENCRYPTION_KEY
  • BETTER_AUTH_SECRET

Auth Provider Secret Convention

auth.providers entries are metadata-only and must not include clientSecret. When auth.providers is non-empty, auth.providersExistingSecret is required. Each provider secret must use the provider-name convention shared by Helm and the runtime:

  • Secret key format: PROVIDER_<SANITIZED_PROVIDER_NAME>_CLIENT_SECRET
  • Env var format: GYRE_AUTH_PROVIDER_<SANITIZED_PROVIDER_NAME>_CLIENT_SECRET
  • Sanitization: uppercase the provider name and replace every non-[A-Z0-9] character with _

Examples:

  • GitHub -> PROVIDER_GITHUB_CLIENT_SECRET
  • Corporate SSO -> PROVIDER_CORPORATE_SSO_CLIENT_SECRET
  • oauth2.generic -> PROVIDER_OAUTH2_GENERIC_CLIENT_SECRET

Upgrade Procedure

To upgrade Gyre:

Before upgrading to a version that requires BETTER_AUTH_SECRET, update the Kubernetes Secret used by the release and add BETTER_AUTH_SECRET first:

kubectl create secret generic gyre-secrets \
--namespace flux-system \
--from-literal=BETTER_AUTH_SECRET="$(openssl rand -hex 32)" \
--dry-run=client -o yaml | kubectl apply -f -

Production no longer falls back to AUTH_ENCRYPTION_KEY; pods will fail to start until BETTER_AUTH_SECRET is present. security-config.ts also requires BETTER_AUTH_SECRET to differ from AUTH_ENCRYPTION_KEY, GYRE_ENCRYPTION_KEY, and BACKUP_ENCRYPTION_KEY, so this upgrade invalidates existing Better Auth sessions and users must sign in again.

# Update Helm repository
helm repo update

# Upgrade release
helm upgrade gyre oci://ghcr.io/entropy0120/charts/gyre \
--namespace flux-system

Upgrade with Backup

# 1. Backup database
POD=$(kubectl get pod -n flux-system -l app.kubernetes.io/name=gyre -o jsonpath='{.items[0].metadata.name}')
kubectl cp flux-system/$POD:/data/gyre.db ./gyre-backup-$(date +%Y%m%d).db

# 2. Perform upgrade
helm upgrade gyre oci://ghcr.io/entropy0120/charts/gyre --namespace flux-system

# 3. Verify
kubectl rollout status deployment/gyre -n flux-system

Rollback

# View history
helm history gyre -n flux-system

# Rollback to previous version
helm rollback gyre -n flux-system

# Rollback to specific revision
helm rollback gyre 2 -n flux-system

Troubleshooting

Common Helm installation issues:

Pod Not Starting

Symptoms: Pod stuck in Pending, CrashLoopBackOff, or ImagePullBackOff

# Check pod status
kubectl get pods -n flux-system -l app.kubernetes.io/name=gyre

# Describe pod for events
kubectl describe pod -n flux-system -l app.kubernetes.io/name=gyre

# Check logs
kubectl logs -n flux-system -l app.kubernetes.io/name=gyre --tail=100

Common Issues:

  • PVC not bound: Check StorageClass and PV availability.
  • Image pull errors: Verify image.repository and imagePullSecrets.
  • Insufficient resources: Check node capacity.

Database Issues

Check PVC status:

kubectl get pvc -n flux-system
kubectl describe pvc gyre-data -n flux-system

RBAC Permission Errors

Test ServiceAccount permissions:

# Check if SA can list FluxCD resources
kubectl auth can-i get gitrepositories.source.toolkit.fluxcd.io
--as=system:serviceaccount:flux-system:gyre
--all-namespaces

Backup and Restore

Automated Backup Script

#!/bin/bash
# backup-gyre.sh

NAMESPACE="flux-system"
BACKUP_DIR="./backups"
DATE=$(date +%Y%m%d-%H%M%S)

mkdir -p $BACKUP_DIR

POD=$(kubectl get pod -n $NAMESPACE -l app.kubernetes.io/name=gyre -o jsonpath='{.items[0].metadata.name}')

if [ -z "$POD" ]; then
echo "Error: No Gyre pod found"
exit 1
fi

echo "Backing up database from pod: $POD"
kubectl cp $NAMESPACE/$POD:/data/gyre.db $BACKUP_DIR/gyre-$DATE.db

echo "Backup completed: $BACKUP_DIR/gyre-$DATE.db"

# Keep only last 10 backups
ls -t $BACKUP_DIR/gyre-*.db | tail -n +11 | xargs -r rm

Restore from Backup

#!/bin/bash
# restore-gyre.sh

NAMESPACE="flux-system"
BACKUP_FILE=$1
PVC_NAME="gyre-data" # Adjust if your PVC name is different

if [ -z "$BACKUP_FILE" ]; then
echo "Usage: $0 <backup-file>"
exit 1
fi

if [ ! -f "$BACKUP_FILE" ]; then
echo "Error: Backup file $BACKUP_FILE not found"
exit 1
fi

# Scale down
echo "Scaling down Gyre deployment..."
kubectl scale deployment gyre -n $NAMESPACE --replicas=0
kubectl wait --for=delete pod -l app.kubernetes.io/name=gyre -n $NAMESPACE --timeout=60s

# Create helper pod to mount the PVC
echo "Creating restore helper pod..."
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: gyre-restore-helper
namespace: $NAMESPACE
spec:
containers:
- name: helper
image: alpine
command: ["sleep", "3600"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: $PVC_NAME
EOF

kubectl wait --for=condition=ready pod gyre-restore-helper -n $NAMESPACE --timeout=60s

# Restore database
echo "Copying database file..."
kubectl cp $BACKUP_FILE $NAMESPACE/gyre-restore-helper:/data/gyre.db

# Cleanup helper
echo "Removing helper pod..."
kubectl delete pod gyre-restore-helper -n $NAMESPACE

# Scale up
echo "Scaling up Gyre deployment..."
kubectl scale deployment gyre -n $NAMESPACE --replicas=1
kubectl wait --for=condition=ready pod -l app.kubernetes.io/name=gyre -n $NAMESPACE --timeout=120s

echo "Database restored successfully from: $BACKUP_FILE"