TractorStackdocs
Docs menu

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 ComposeKubernetes
healthcheckLiveness and readiness probes
env_file, environmentConfigMap and Secret
Named volumesPersistentVolumeClaim
restart: unless-stoppedDeployment controller keeps replicas running
portsService, plus Ingress for HTTP
depends_on with a health conditionReadiness probes, sometimes init containers
deploy.resourcesResource requests and limits
Named networksNamespaces and NetworkPolicy
profilesOptional 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