{
  "id": "deploy",
  "title": "Deploy",
  "url": "https://redis.io/docs/latest/operate/featureform/deploy/",
  "summary": "Deploy and operate Feature Form on Kubernetes.",
  "tags": [
    "docs",
    "operate",
    "featureform"
  ],
  "last_updated": "2026-04-20T15:33:16+02:00",
  "page_type": "content",
  "content_hash": "dfff16086b20255e1bcaca2fa6a0480af86371351abe09e8225b9834377c65d6",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "Use this guide to install Feature Form with the Helm chart and verify that the core services are healthy."
    },
    {
      "id": "install",
      "title": "Install",
      "role": "setup",
      "text": "The default documented path is OIDC-enabled auth plus durable PostgreSQL-backed state."
    },
    {
      "id": "prerequisites",
      "title": "Prerequisites",
      "role": "content",
      "text": "- Kubernetes 1.27+\n- Helm 3.14+\n- an OIDC issuer URL and client ID\n- a PostgreSQL connection path or existing secret"
    },
    {
      "id": "1-choose-auth-and-state-values",
      "title": "1. Choose auth and state values",
      "role": "content",
      "text": "Pick one PostgreSQL-backed state path before installation:\n\n- `postgres.url`\n- `postgres.secretName`\n- `addons.statePostgres.enabled=true`\n\nExternal PostgreSQL is the documented durable default."
    },
    {
      "id": "2-pick-the-base-chart-or-a-profile",
      "title": "2. Pick the base chart or a profile",
      "role": "content",
      "text": "- Base chart for environments where provider infrastructure already exists\n- `profiles/memory.yaml` for local or test-only installs\n- `profiles/provider-stack.yaml` for bundled providers\n- `profiles/observability-postgres.yaml` for observability\n- `profiles/provider-observability.yaml` for both"
    },
    {
      "id": "3-install-with-helm",
      "title": "3. Install with Helm",
      "role": "content",
      "text": "[code example]"
    },
    {
      "id": "4-validate-pods-and-services",
      "title": "4. Validate pods and services",
      "role": "content",
      "text": "[code example]\n\nLook for a healthy shared API deployment, both REST and gRPC services, and completed migrations when PostgreSQL state is enabled."
    },
    {
      "id": "5-record-the-endpoints",
      "title": "5. Record the endpoints",
      "role": "content",
      "text": "Capture the URLs or hosts your teams will need:\n\n- REST API endpoint\n- gRPC endpoint\n- dashboard URL if enabled\n- Grafana URL if enabled"
    },
    {
      "id": "high-risk-confusion-points",
      "title": "High-risk confusion points",
      "role": "content",
      "text": "- One shared server deployment exposes both REST and gRPC; they are not separate deployments.\n- `auth.enabled=false` is not supported.\n- `stateBackend=memory` is not durable.\n- The dashboard needs more than `dashboard.enabled=true`; it also needs correct auth and API URL settings."
    },
    {
      "id": "configure-external-access",
      "title": "Configure external access",
      "role": "configuration",
      "text": "Use this section after installation to publish the right Feature Form endpoints for users, automation, and optional UI access."
    },
    {
      "id": "rest-ingress-example",
      "title": "REST ingress example",
      "role": "content",
      "text": "[code example]"
    },
    {
      "id": "grpc-exposure-guidance",
      "title": "gRPC exposure guidance",
      "role": "content",
      "text": "Use `grpc.ingress.*` only with an ingress controller that supports gRPC backends. If ingress is not a fit, use `grpc.service.type=LoadBalancer`."
    },
    {
      "id": "dashboard-requirements",
      "title": "Dashboard requirements",
      "role": "content",
      "text": "A working dashboard path needs all of the following:\n\n- `dashboard.enabled=true`\n- a resolvable public API URL\n- dashboard auth secrets\n- a resolvable auth URL"
    },
    {
      "id": "unified-ingress",
      "title": "Unified ingress",
      "role": "content",
      "text": "Unified ingress publishes one host with chart-managed paths for API, dashboard, and optionally Grafana. Do not combine it with service-specific ingress settings."
    },
    {
      "id": "direct-load-balancers",
      "title": "Direct load balancers",
      "role": "content",
      "text": "If your platform prefers direct external services, expose:\n\n- `rest.service.type=LoadBalancer`\n- `grpc.service.type=LoadBalancer`\n- `dashboard.service.type=LoadBalancer`"
    },
    {
      "id": "common-validation-failures",
      "title": "Common validation failures",
      "role": "content",
      "text": "- missing ingress hosts\n- unified ingress mixed with service-specific ingresses\n- dashboard enabled without API URL or auth secrets\n- Grafana ingress configured without the observability stack enabled"
    }
  ],
  "examples": [
    {
      "id": "3-install-with-helm-ex0",
      "language": "bash",
      "code": "helm upgrade --install featureform charts/featureform \\\n  --set postgres.url=postgres://featureform:featureform@my-postgres:5432/featureform?sslmode=disable \\\n  --set auth.oidcIssuerURL=https://idp.example.com/realms/featureform \\\n  --set auth.oidcClientID=featureform-api \\\n  --set rest.ingress.enabled=true \\\n  --set rest.ingress.className=nginx \\\n  --set rest.ingress.hosts[0].host=api.example.com \\\n  --set rest.ingress.hosts[0].paths[0].path=/ \\\n  --set rest.ingress.hosts[0].paths[0].pathType=Prefix",
      "section_id": "3-install-with-helm"
    },
    {
      "id": "4-validate-pods-and-services-ex0",
      "language": "bash",
      "code": "kubectl get pods -n <namespace>\nkubectl get svc -n <namespace>\nkubectl describe deployment featureform-featureform-server -n <namespace>",
      "section_id": "4-validate-pods-and-services"
    },
    {
      "id": "rest-ingress-example-ex0",
      "language": "bash",
      "code": "helm upgrade --install featureform charts/featureform \\\n  --set postgres.url=postgres://featureform:featureform@my-postgres:5432/featureform?sslmode=disable \\\n  --set auth.oidcIssuerURL=https://idp.example.com/realms/featureform \\\n  --set auth.oidcClientID=featureform-api \\\n  --set rest.ingress.enabled=true \\\n  --set rest.ingress.className=nginx \\\n  --set rest.ingress.hosts[0].host=api.example.com \\\n  --set rest.ingress.hosts[0].paths[0].path=/ \\\n  --set rest.ingress.hosts[0].paths[0].pathType=Prefix",
      "section_id": "rest-ingress-example"
    }
  ]
}
