Docs / Grow in stages
Kubernetes-ready rules
Planned design. TractorStack is in development. This page describes how it is designed to work; nothing here is available to install yet. See the roadmap for the status of each part.
In design
Moving from Docker Compose to Kubernetes is only painful when the applications were never built to move. TractorStack’s design applies six rules from stage 1, while everything still runs on one server. They cost very little on day one and save a rewrite later. If you never go past stage 2, you still end up with services that are easier to back up, restart and debug.
The six rules
1. No state on local disk
Why: in Kubernetes a container can be rescheduled to another node at any time. Anything written inside it, or to a folder on one host, is left behind.
Stage 1: applications keep data in PostgreSQL, files in RustFS over the S3 API, and short-lived data in Valkey if they need it. The data services themselves use named volumes; the apps don’t.
Later: the same apps run as stateless Deployments and scale by adding replicas.
2. Configuration from environment variables and secrets
Why: config baked into an image means a new build for every environment.
Stage 1: an env_file per service, with secrets kept out of Git in plain text (see Security).
Later: the same variable names come from a ConfigMap and a Secret, so the app code doesn’t change.
3. Health endpoints and graceful shutdown
Why: an orchestrator can only restart or route around a service it can ask “are you alive?” and “are you ready?”.
Stage 1: each service exposes something like /healthz and /readyz, used by a Compose healthcheck. On SIGTERM it finishes in-flight requests and exits.
Later: the same endpoints back liveness and readiness probes, which rolling updates depend on.
4. Images from your own registry, pinned
Why: :latest means two hosts can run different code under the same name, and a public registry outage can stop a restart.
Stage 1: images are pulled from the local registry with a fixed version tag or digest.
Later: Helm values reference the same registry and tags. It also matters for offline sites.
5. Logs to stdout, metrics in Prometheus format
Why: log files inside containers fill disks and vanish with the container.
Stage 1: Docker collects stdout; services expose a /metrics endpoint that the monitoring stack scrapes.
Later: cluster log collectors and Prometheus pick up the same output with no app changes.
6. Backups to S3 from the start
Why: if stage 1 backups land in an S3 bucket, later stages can restore from them directly. That is what makes the data move calm instead of rushed.
Stage 1: pgBackRest writes to a RustFS bucket. See Backups.
Later: new database servers, or an operator such as CloudNativePG in stage 4, can start from those same backups.
Compose and Kubernetes equivalents
| Docker Compose | Kubernetes |
|---|---|
healthcheck | Liveness and readiness probes |
env_file, environment | ConfigMap and Secret |
Named volumes | PersistentVolumeClaim |
restart: unless-stopped | Deployment controller keeps replicas running |
ports | Service, plus Ingress for HTTP |
depends_on with a health condition | Readiness probes, sometimes init containers |
deploy.resources | Resource requests and limits |
| Named networks | Namespaces and NetworkPolicy |
profiles | Optional parts switched on in Helm values |
The mapping is not perfect. Kubernetes has no direct equivalent of depends_on, so apps should retry their connections rather than assume start order. That habit is worth having in Compose too.
What a rule-following service looks like
A planned example, not taken from a release:
# compose/app.yaml (illustrative)
services:
api:
image: registry.internal/acme/api:1.4.2
env_file: ./env/api.env
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8080/readyz"]
interval: 15s
stop_grace_period: 30s
restart: unless-stopped
You don’t need to adopt Kubernetes to follow these rules. Most of them are good practice for any service. See Moving between stages for how they pay off.
Last updated 25 October 2026 · Questions or corrections: sales@infratractor.com