---
title: "Docker and Kubernetes"
description: "Nextvision Status — Docker and Kubernetes"
---

> Documentation Index
> Fetch the complete documentation index at: https://status.nextvisions.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Docker and Kubernetes

## Production dependencies

Use PostgreSQL 17+, Redis 7+ and an S3-compatible MinIO endpoint with a private bucket. Supply `DATABASE_URL`, `REDIS_URL`, `MINIO_ENDPOINT`, `MINIO_ACCESS_KEY`, `MINIO_SECRET_KEY`, `MINIO_BUCKET`, `MINIO_TLS`, SMTP settings, `PUBLIC_URL` and `OAUTH_CLIENTS` through your secret manager. URL credentials must be percent-encoded.

Use a dedicated schema owner for auth, scheduling and public snapshot construction, plus `status_runtime` for tenant transactions. The owner does not need SUPERUSER or BYPASSRLS. Provision the NOLOGIN runtime role before migration on managed PostgreSQL, then grant the owner SET ROLE without inheriting runtime privileges. Migrations require ownership/DDL rights; initial role creation requires a separate bootstrap operator if the owner has no CREATEROLE.

Tenant tables retain FORCE RLS. Migration `011` adds explicit policies for the schema owner; switching to `status_runtime` still enforces organization isolation. Never expose either database credential to clients. Use verified TLS, including the provider CA where required.

## Build

```sh
docker build --build-arg SOURCE_SHA=SOURCE_SHA -t registry/nextvision-status:SOURCE_SHA .
docker build --build-arg SOURCE_SHA=SOURCE_SHA -t registry/nextvision-status-web:SOURCE_SHA apps/web
docker build --build-arg SOURCE_SHA=SOURCE_SHA \
  --build-arg DOCS_SITE_URL=https://status.nextvisions.ai --build-arg DOCS_BASE=/docs/ \
  -t registry/nextvision-status-docs:SOURCE_SHA apps/docs
```

Configure web `API_INTERNAL_URL` and `DOCS_URL` at runtime; use `DOCS_URL=/docs/` for the same-origin deployment. No environment-specific frontend rebuild is required. The API remains internal behind the Next.js proxy. Docs are static, built with `/docs/` as their base and the Production canonical URL; Dev sends `X-Robots-Tag: noindex, nofollow`. Docs may also run separately on Cloudflare.

SMTP accepts `SMTP_TLS_MODE=auto|implicit|starttls|none`. Port 465 uses `implicit` with certificate verification; `none` refuses credentials. Dev uses private Mailpit. Supply Production SMTP credentials through a separate Secret, never through image build arguments.

## Helm

Create an existing Kubernetes Secret named `status-secrets` containing the configuration above. Build/push images and record immutable digests. Copy `values.yaml` into an environment overlay and replace the image names, public URL, ingress host and TLS secret.

```sh
helm lint deploy/helm/nextvision-status
helm template status deploy/helm/nextvision-status -f production-values.yaml
```

For a standalone self-host installation with `gitops.enabled=false`, install the reviewed overlay with Helm. For the Nextvision environments, commit rendered manifests to GitOps and let Argo deploy; do not run a parallel Helm upgrade against these namespaces. Enable `gitops.enabled` and `postSync.enabled`, with the PostSync test image pinned by digest. Migration is an Argo PreSync Job and acceptance is an Argo PostSync Job. A Helm test hook is not release acceptance evidence.

Services use readiness/liveness checks, non-root processes, read-only filesystems and graceful shutdown. HPA is opt-in. Match NetworkPolicy to the real ingress and database paths: Traefik hostNetwork may arrive from node/tunnel addresses, and PostgreSQL NodePort traffic may be translated to its compute Pod/port. Allow only the environment's compute. Redis uses AOF/PVC; the configured single Longhorn replica is not HA or a backup.

Start with one worker replica: scheduler/evaluator transactions are safe to retry, but increased replicas require testing contention against your workload. Helm-rendering success does not prove a cluster rollout.

## CI and promotion

GitHub is canonical source. Exact `dev/main` SHAs synchronize to private GitLab. GitLab loads the CI configuration/controller from protected `ci-control-v3`, runs Go race/vet/integration, non-root libpq, Next.js/Nimbus and Helm/gate tests, then builds immutable backend/web/docs and E2E images. Integration uses disposable PostgreSQL, Redis, MinIO and Mailpit without a Docker daemon.

The release controller commits digests to `dev-gitops`; Argo must reconcile that exact revision, become Healthy and finish the full sync and PostSync. PostSync tests two organizations, memberships, plans, branding, MCP keys, SQL RLS and snapshot fallback through an API with unavailable DB/Redis. Only then does a GitHub-hosted runner perform read-only public acceptance. Source, tree, jobs, digests, GitOps revision, hook UID/log and external run are retained as evidence.

`main` does not deploy Production automatically. The designated GitLab Owner manually runs `promote-production`; the job checks Owner identity, current main HEAD/tree, accepted Dev evidence and Production GitOps HEAD. It reuses the same digests without rebuilding. Production needs its own PostSync/public acceptance before PASS. Missing or failed evidence blocks promotion even when workloads already serve traffic.

Keep Argo cluster watches namespace-scoped when Kubernetes permissions are namespace-scoped. Its AppProject must permit observing Pod/ReplicaSet/ControllerRevision descendants for hook UID/log evidence; Kubernetes RBAC can still deny creating them directly. CI receives only an Argo observer credential, never a Kubernetes writer. See the repository's `docs/devops/` for operational mappings and bootstrap overrides.

## Rollback

Commit the previously verified chart/configuration/digests to the environment GitOps branch with a normal push and a current-HEAD check. Argo must complete a full sync with new PostSync evidence and public acceptance. Do not force-push or substitute selective sync. Migrations are forward-only; reverting images/configuration does not restore data. Database recovery needs an explicit backup and recovery-point decision. A configuration rollback drill does not prove image rollback or database restore.

Source: https://status.nextvisions.ai/docs/en/deployment/index.mdx
