Skip to main content

Container Deployment: Running kt gateway in Docker and Kubernetes

The Keeptrusts gateway is often first evaluated as a local process, but production behavior depends on more than a successful local run. Teams need repeatable startup, explicit config mounting, controlled secret injection, health probes, and a clear path to horizontal scaling. Container deployment gives you those operational boundaries without changing the gateway model itself. It is still the same kt gateway run runtime, just packaged in a way that works under real service management.

Use this page when

  • You are moving a local gateway setup into Docker or Kubernetes.
  • You need a repeatable deployment pattern with mounted config and environment-based secrets.
  • You want probes, restarts, and scaling behavior that match production expectations.

Primary audience

  • Primary: DevOps and platform engineers
  • Secondary: Technical Leaders planning production topology

The problem

Running the gateway as a local shell process is fine for development, but it leaves several production concerns implicit.

Where does the config file come from? How are provider credentials injected? How does the orchestrator know whether the gateway is ready to accept traffic? How do you restart it safely? How do you run multiple replicas when throughput grows?

Without a container pattern, teams often solve those questions in inconsistent ways. One host has credentials in a shell profile, another in a system service. One environment uses a copied config file, another relies on a manually edited path. Health verification becomes a person checking logs instead of the platform checking a probe.

The result is avoidable operational variance. The gateway itself may be correct, but the deployment contract around it is weak.

The solution

Keeptrusts fits cleanly into container deployment because the runtime surface is explicit.

The gateway needs three things: a policy config, provider credentials, and, when you want control-plane reporting or managed mode, KEEPTRUSTS_API_URL plus KEEPTRUSTS_API_TOKEN. That maps naturally to mounted files, environment variables, ConfigMaps, and Secrets.

Docker is the fastest way to make the runtime repeatable. Kubernetes is the next step when you need declarative rollout, probes, and horizontal scale. The important point is that the gateway behavior does not have to change between them.

Implementation

For a config-defined runtime in Docker, mount the policy file read-only and keep credentials in environment variables:

docker run -d \
--name keeptrusts-gateway \
-p 41002:41002 \
-e KEEPTRUSTS_API_URL="https://api.keeptrusts.com" \
-e KEEPTRUSTS_API_TOKEN="$KEEPTRUSTS_API_TOKEN" \
-e OPENAI_API_KEY="$OPENAI_API_KEY" \
-v "$PWD/policy-config.yaml:/etc/keeptrusts/policy-config.yaml:ro" \
keeptrusts/gateway:latest \
gateway run --listen 0.0.0.0:41002 --policy-config /etc/keeptrusts/policy-config.yaml

That pattern has two advantages. First, the config lives outside the image, so deployment does not require rebuilding a container for every policy revision. Second, secrets stay in runtime environment injection instead of inside the YAML file.

If you run a managed fleet, the container pattern can be even smaller because the gateway pulls its runtime state from the control plane:

docker run -d \
--name keeptrusts-managed-gateway \
-e KEEPTRUSTS_API_URL="https://api.keeptrusts.com" \
-e KEEPTRUSTS_API_TOKEN="$KEEPTRUSTS_API_TOKEN" \
-e KEEPTRUSTS_GATEWAY_ID="production" \
-e OPENAI_API_KEY="$OPENAI_API_KEY" \
keeptrusts/kt:latest run --gateway-id production

Use that model when you want the container to hot-reload centrally managed configuration rather than mounting a local file.

For Kubernetes, the cleanest pattern is a Deployment with a ConfigMap for policy-config.yaml, a Secret for control-plane auth, and HTTP probes on /health:

apiVersion: apps/v1
kind: Deployment
metadata:
name: keeptrusts-gateway
spec:
replicas: 3
selector:
matchLabels:
app: keeptrusts-gateway
template:
metadata:
labels:
app: keeptrusts-gateway
spec:
containers:
- name: gateway
image: keeptrusts/gateway:latest
args:
- gateway
- run
- --listen
- 0.0.0.0:41002
- --policy-config
- /etc/keeptrusts/policy-config.yaml
env:
- name: KEEPTRUSTS_API_URL
value: https://api.keeptrusts.com
- name: KEEPTRUSTS_API_TOKEN
valueFrom:
secretKeyRef:
name: keeptrusts-api-key
key: api-key
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: openai-api-key
key: api-key
volumeMounts:
- name: policy-config
mountPath: /etc/keeptrusts
readOnly: true
livenessProbe:
httpGet:
path: /health
port: 41002
readinessProbe:
httpGet:
path: /health
port: 41002
volumes:
- name: policy-config
configMap:
name: keeptrusts-policy-config

Once the Deployment exists, your verification loop should stay small:

  1. Check the probe surface with curl -fsS http://localhost:41002/health.
  2. Run kt doctor from an operator environment.
  3. Send a governed test request through /v1/chat/completions.
  4. Confirm decision evidence with kt events tail --since 5m --json.

That sequence is the same in Docker and Kubernetes. Only the process manager changes.

The most common operational mistake is baking secrets or mutable config into the image itself. Keeptrusts already gives you secret_key_ref and environment-driven control-plane auth. Use them. The container image should carry the runtime, not the deployment-specific credentials.

Another common mistake is skipping readiness checks because the container “started successfully.” For a gateway, container start is not the same as traffic readiness. The /health endpoint should decide when the orchestrator sends traffic, not human optimism.

Results and impact

Container deployment gives Keeptrusts the same operational advantages teams already expect from application workloads: reproducible startup, consistent secret injection, standardized health checks, and clean rollout behavior.

Kubernetes adds the next layer: multiple replicas, automated restarts, and controlled rollouts. That matters once governance traffic becomes shared infrastructure instead of a single developer tool.

Key takeaways

  • The Keeptrusts gateway moves cleanly from local process to container runtime without changing its core operating model.
  • Use mounted config plus environment-injected secrets for Docker.
  • Use ConfigMaps, Secrets, and /health probes for Kubernetes.
  • Choose config-defined runtime for local or simpler deployments and managed mode when you want central configuration polling.
  • Treat readiness as an HTTP contract, not a manual log inspection step.

Next steps