Skip to content

OpenReel Video

OpenReel Video is a browser-based video editor. The HelmForge chart serves the static application with hardened runtime defaults and modern Kubernetes exposure options.

Key Features

  • HelmForge-maintained docker.io/helmforge/openreel-video:v0.5.0 image
  • Static hosting for the upstream browser-based editor
  • WebCodecs-ready deployment with writable temporary volume support
  • Ingress, Gateway API through the single gateway values block, dual-stack Service fields, HPA, PDB, NetworkPolicy, and Helm tests
  • Non-root runtime with dropped Linux capabilities

Installation

helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install openreel-video helmforge/openreel-video --namespace openreel-video --create-namespace
helm install openreel-video oci://ghcr.io/helmforgedev/helm/openreel-video --namespace openreel-video --create-namespace

Examples

Ingress:

ingress:
  enabled: true
  ingressClassName: nginx
  hosts:
    - host: video.example.com
      paths:
        - path: /
          pathType: Prefix

Gateway API:

gateway:
  enabled: true
  parentRefs:
    - name: public
  hostnames:
    - video.example.com

Operations

The chart is stateless by default. Scale horizontally with HPA when the ingress layer can distribute requests across replicas.

Architecture

OpenReel Video is deployed as a stateless web workload. The chart is designed for browser-based editing frontends and WebCodecs-ready static hosting, so the main operational concerns are routing, cache behavior, temporary writable storage, and safe horizontal scaling.

Runtime flow:

  1. Ingress or Gateway API receives public HTTPS traffic.
  2. The Service load-balances requests across OpenReel Video pods.
  3. The container serves static assets and browser application code.
  4. Temporary files are written only to the configured tmpVolume.
  5. Optional HPA and PDB keep the frontend available during rollouts.

Production Values

Use multiple replicas, explicit resources, NetworkPolicy, and either Ingress or Gateway API:

replicaCount: 2

service:
  ipFamilyPolicy: PreferDualStack
  ipFamilies:
    - IPv4
    - IPv6

ingress:
  enabled: true
  ingressClassName: traefik
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: openreel.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: openreel-video-tls
      hosts:
        - openreel.example.com

networkPolicy:
  enabled: true
  extraEgress: []

resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 256Mi

ExternalName Compatibility

When the Kubernetes Service should point clients at an externally hosted OpenReel endpoint, use ExternalName and keep Ingress/Gateway disabled:

service:
  type: ExternalName
  externalName: openreel-static.example.com

ingress:
  enabled: false

gateway:
  enabled: false

This is useful during migration from external hosting into the cluster, or when consumers need a stable Kubernetes DNS name for a service that remains outside Kubernetes.

ExternalName changes only the Service into a DNS alias. The chart still renders its local Deployment and Helm test, but the Service no longer selects those pods. helm test follows the alias and expects the external target to provide OpenReel’s /healthz, landing page, and COEP response header; the test fails when the external service does not satisfy that contract.

Gateway API

Gateway API is first-class and uses the shared HelmForge gateway shape:

gateway:
  enabled: true
  parentRefs:
    - name: public
      namespace: gateway-system
  hostnames:
    - openreel.example.com
  path: /
  pathType: PathPrefix

Scaling And Rollouts

The chart is stateless, so HPA is safe when the edge layer can distribute requests:

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 6

pdb:
  enabled: true
  minAvailable: 1

Keep tmpVolume.enabled=true unless your custom image does not need writable temporary storage. The root filesystem can remain read-only while /tmp stays writable.

Security Contract

The pinned image declares user 101, exposes port 8080, and starts unprivileged NGINX. The chart runs it with RuntimeDefault seccomp, no Service Account token, no privilege escalation, a read-only root filesystem, and all Linux capabilities dropped. A bounded emptyDir at /tmp is the only writable runtime path required by the image.

The NGINX listener is fixed at 8080. Keep service.targetPort=8080; changing the Kubernetes port value alone does not reconfigure the process and causes probes and traffic to fail. Preserve the image’s COOP and COEP response headers through any Ingress, Gateway, CDN, or reverse proxy.

Upgrade Compatibility

The quality update preserves the rendered workload defaults. Upgrades from chart 1.0.4 were validated through both a normal Helm upgrade and an upgrade with --reuse-values. Both paths preserved the image, pod and container security contexts, /tmp volume, Service ports, and Ready replica count.

Review stored values before upgrading:

helm get values openreel-video -n openreel-video
helm upgrade openreel-video helmforge/openreel-video \
  --namespace openreel-video \
  --reuse-values

Validation

After deployment:

helm test openreel-video -n openreel-video
kubectl get pods -n openreel-video -l app.kubernetes.io/name=openreel-video
kubectl logs -n openreel-video deploy/openreel-video --since=10m
kubectl get events -n openreel-video --sort-by=.lastTimestamp

For public routes, validate that static assets load with the same host, scheme, and path used by the browser.

Common Issues

Symptom Likely Cause Fix
Blank page after route exposure Base URL or static asset path does not match the route Check browser network errors and Gateway/Ingress path settings.
Pods fail with read-only filesystem errors Application writes outside tmpVolume Mount an explicit writable volume for the path or fix the image.
HPA scales but requests still hit one pod Edge proxy affinity or cache behavior Review ingress/gateway load-balancing settings.
ExternalName has no endpoints Expected Kubernetes behavior Validate DNS resolution from a client pod instead of checking Endpoints.

Values

Parameter Default Description
global {} Parent-chart and platform integration values.
nameOverride, fullnameOverride "" Resource naming overrides.
commonLabels {} Labels added to chart resources.
replicaCount 1 Pod count when autoscaling is disabled.
revisionHistoryLimit 3 Retained Deployment revisions.
image.repository docker.io/helmforge/openreel-video HelmForge OpenReel Video image.
image.tag v0.5.0 Pinned image tag.
image.pullPolicy IfNotPresent Container image pull policy.
imagePullSecrets [] Private registry credentials.
serviceAccount.create true Create a dedicated ServiceAccount.
serviceAccount.name "" Existing or generated ServiceAccount name.
serviceAccount.annotations {} ServiceAccount annotations.
serviceAccount.automountServiceAccountToken false Mount Kubernetes API credentials.
service.type ClusterIP Kubernetes Service type.
service.externalName "" Required DNS name for ExternalName mode.
service.port 80 Client-facing Service port.
service.targetPort 8080 Fixed NGINX target; keep this at 8080.
service.annotations {} Service annotations.
service.ipFamilyPolicy "" Optional dual-stack policy.
service.ipFamilies [] Optional IP family list.
ingress.enabled false Render Ingress.
ingress.ingressClassName "" Ingress controller class.
ingress.annotations, ingress.tls {}, [] Ingress metadata and TLS entries.
ingress.hosts openreel.local Ingress hosts and paths.
gateway.enabled false Render a Gateway API HTTPRoute.
gateway.parentRefs, gateway.hostnames [], [] HTTPRoute parents and hostnames.
gateway.path, gateway.pathType /, PathPrefix HTTPRoute path match.
networkPolicy.enabled false Restrict ingress and deny egress by default.
networkPolicy.ingress [] Custom inbound rules.
networkPolicy.egress [] Custom egress rules.
networkPolicy.extraEgress [] Additional full egress rules.
autoscaling.enabled false Render HPA.
autoscaling.minReplicas, maxReplicas 1, 4 Autoscaling range.
autoscaling.targetCPUUtilizationPercentage 70 CPU utilization target.
autoscaling.targetMemoryUtilizationPercentage 80 Memory utilization target.
pdb.enabled, pdb.minAvailable true, 1 Disruption protection.
probes.liveness, probes.readiness enabled /healthz probe flags, paths, and timing.
resources small requests and limits Container CPU and memory budget.
podSecurityContext UID/GID 101 Verified non-root pod identity and seccomp.
securityContext hardened Read-only root, no escalation, drop all capabilities.
podAnnotations, podLabels {}, {} Pod metadata.
priorityClassName "" PriorityClass name.
terminationGracePeriodSeconds 30 Graceful shutdown period.
nodeSelector, tolerations, affinity {}, [], {} Pod placement controls.
topologySpreadConstraints [] Topology distribution rules.
tmpVolume.enabled, tmpVolume.sizeLimit true, 64Mi Writable NGINX temporary volume.
test.image busybox:1.37.0 Helm test image and pull policy.
extraObjects [] Additional templated Kubernetes manifests.