> For the complete documentation index, see [llms.txt](https://docs.kangal.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kangal.dev/production-operations/deployment.md).

# Deployment

Use Docker Compose for local development and isolated demonstrations. Use the signed production Helm package for shared, staging, and production environments. The Compose file includes local-only credentials, single-node dependencies, and host ports; it is not a production topology.

## Deployment modes

The chart supports four modes:

| Mode            | Components                          | Use case                                                      |
| --------------- | ----------------------------------- | ------------------------------------------------------------- |
| `standalone`    | API and frontend                    | Evaluation or a small private control plane                   |
| `control-plane` | API and frontend                    | Production control plane with separately deployed data planes |
| `data-plane`    | Independent data plane              | Regional or edge runtime connected to a control plane         |
| `split`         | API, frontend, and proxy/data plane | Combined regional installation                                |

Background workers are independently enabled. Production should run API producers and workers as separate Deployments so job execution does not compete with request handling.

## Prerequisites

* Kubernetes with a supported ingress or Gateway API implementation;
* Helm 3 and `kubectl` access to the target namespace;
* external MongoDB with replica-set or sharded-cluster transactions;
* authenticated, persistent Redis;
* an existing runtime Secret or external secret operator;
* immutable API, frontend, and data-plane images from the same release;
* DNS, TLS issuer, storage, monitoring, and alerting prepared by the platform team.

Download and verify the signed chart package attached to the selected release, then point `KANGAL_CHART` at the unpacked chart or package:

```bash
export KANGAL_CHART=/secure/path/kangal-<chart-version>.tgz
export RELEASE=kangal
export NAMESPACE=kangal
```

## Runtime Secret contract

Create the runtime Secret through your secret delivery system before rendering the release. The API and workers need the same database, Redis, signing, and field-encryption material. Keep values out of shell history and Helm command arguments.

The Secret normally exposes keys such as `MONGODB_URL`, `REDIS_URL`, `SECRET_KEY`, `FIELD_ENCRYPTION_KEY`, OAuth/SMTP credentials, and provider credentials. Multi-region workers also require one shared durable-job Redis URL. See [Secrets](/production-operations/secrets.md).

## Production values

Keep an environment overlay in a protected deployment repository. The following is a shape, not a complete environment file:

```yaml
deploymentMode: control-plane

global:
  imagePullSecrets:
    - name: kangal-registry

api:
  replicaCount: 3
  image:
    repository: registry.example.com/kangal-api
    tag: "<immutable-release-tag>"
    pullPolicy: IfNotPresent
  config:
    APP_ENV: production
    KANGAL_BACKGROUND_JOBS_BACKEND: redis-streams
    KANGAL_BACKGROUND_JOBS_RUN_WORKER: "false"
  extraEnvFrom:
    - secretRef:
        name: kangal-runtime
  autoscaling:
    enabled: true
    minReplicas: 3
    maxReplicas: 12
  podDisruptionBudget:
    enabled: true
    minAvailable: 2
  networkPolicy:
    enabled: true

backgroundJobs:
  enabled: true
  replicaCount: 2
  networkPolicy:
    enabled: true

frontend:
  replicaCount: 3
  image:
    repository: registry.example.com/kangal-frontend
    tag: "<immutable-release-tag>"
  config:
    NODE_ENV: production
    API_BASE_URL: http://kangal-api:8001
  autoscaling:
    enabled: true
    minReplicas: 3
    maxReplicas: 10
  podDisruptionBudget:
    enabled: true
    minAvailable: 2
  networkPolicy:
    enabled: true

mongodb:
  enabled: false
  external:
    enabled: true
    connectionSecret:
      name: kangal-runtime
      key: MONGODB_URL
    topology:
      mode: replicaset
      verified: true

redis:
  enabled: false

ingress:
  enabled: true
  className: nginx
  hosts:
    - host: console.example.com
      front:
        path: /
        pathType: Prefix
      api:
        paths:
          - path: /admin
          - path: /api
          - path: /auth
          - path: /health
          - path: /ready
  tls:
    - secretName: kangal-tls
      hosts:
        - console.example.com
```

Review egress rules before enabling NetworkPolicy. DNS, MongoDB, Redis, observability, identity, email, AI providers, and configured upstreams must remain reachable. A policy that only opens ports without restricting destinations is a starting point, not a complete allowlist.

## Render and validate

Run all checks against the exact chart and overlay that will be deployed:

```bash
helm dependency build "$KANGAL_CHART"
helm lint "$KANGAL_CHART" -f values.production.yaml
helm template "$RELEASE" "$KANGAL_CHART" \
  --namespace "$NAMESPACE" \
  -f values.production.yaml > /tmp/kangal-rendered.yaml
kubectl apply --dry-run=server -f /tmp/kangal-rendered.yaml
```

Review the rendered image tags, Secret references, ServiceAccount token mounting, security contexts, writable volumes, probes, Services, ingress, PDB, HPA, and network policies. Rendering does not prove that external dependencies are reachable.

## Install or upgrade

Take a verified database backup for changes that include schema, configuration, or state migration. Then deploy:

```bash
helm upgrade --install "$RELEASE" "$KANGAL_CHART" \
  --namespace "$NAMESPACE" \
  --create-namespace \
  -f values.production.yaml \
  --atomic \
  --cleanup-on-fail \
  --wait \
  --wait-for-jobs \
  --timeout 15m \
  --history-max 10
```

`--atomic` restores the previous Helm revision when the release fails. It does not restore MongoDB, Redis, or Kangal configuration changed by a migration or operator.

When a release introduces a new durable-job payload version, deploy compatible workers before API producers. Keep the newer workers available until older stream entries drain; incompatible entries fail closed instead of being guessed.

## Acceptance checks

```bash
kubectl -n "$NAMESPACE" get deploy,pod,svc,ingress,hpa,pdb
kubectl -n "$NAMESPACE" wait \
  --for=condition=Available deployment \
  -l app.kubernetes.io/instance="$RELEASE" \
  --timeout=10m
kubectl -n "$NAMESPACE" logs \
  -l app.kubernetes.io/instance="$RELEASE",app.kubernetes.io/component=api \
  --tail=200
curl -fsS https://console.example.com/health
curl -fsS https://console.example.com/ready
```

Also verify login, one authenticated admin read, one routed test request, worker health, queue depth, MongoDB transaction capability, Redis persistence, metrics scraping, and certificate presentation. Run protocol or load gates when the change touches routing, TLS, WebSocket, gRPC, TCP, plugins, or upstream handling.

## Rollback

```bash
helm history "$RELEASE" -n "$NAMESPACE"
helm rollback "$RELEASE" <revision> -n "$NAMESPACE" --wait --timeout 10m
```

Before rollback, check release notes for data compatibility. If state restoration is required, freeze writes and follow [Backup and restore](/production-operations/backup-restore.md) or the configuration rollback workflow. Record the old and new Helm revisions, image digests, reason, timestamps, and post-rollback smoke evidence.

## Responsibility boundary

The chart renders and Kubernetes executes the declared workload controls. Operators remain responsible for correct values, dependency topology, secret creation, network allowlists, storage, certificate issuer readiness, capacity, acceptance testing, and rollback authorization.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.kangal.dev/production-operations/deployment.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
