Skip to content
willowark

Containers that behave the same on a laptop and in production

Containerization packages an application with everything it needs to run; orchestration keeps fleets of those containers healthy across machines. Together they remove the classic failure mode of software that works in one environment and mysteriously breaks in the next — and the midnight scramble when a single host dies.

Willowark builds container platforms sized to the team that will run them. Sometimes that is Kubernetes with GitOps delivery; often it is ECS, Cloud Run, or Nomad, which carry far less operational weight. We containerize the application properly first — small images, health checks, graceful shutdown — because orchestration cannot fix a container that misbehaves.

Illustrative: a quiet server room with blue status lightsCloud & Infrastructure

How the work gets done

The same way every time: scope, build, hand over.

The work spans multi-stage Docker builds that cut image size and attack surface, resource requests and limits set from measured usage rather than folklore, liveness and readiness probes that reflect real health, horizontal autoscaling tuned to actual load patterns, and networking — ingress, service discovery, TLS termination. On Kubernetes we add the operational layer: namespace and RBAC design, pod disruption budgets, and GitOps with Argo CD or Flux so cluster state is always traceable to a commit.

In production, orchestration should make whole categories of incidents disappear: a node failure reschedules workloads without a page, a traffic spike scales the service before users notice, and a bad image rolls back to the previous tag in one command. We measure success by what stops happening — manual restarts, capacity guesswork, and environment-specific bugs.

We scope by looking at the application first and the platform second. A short audit of the codebase and runtime behavior — startup time, memory profile, how it handles signals, where it writes files — tells us how much containerization work is needed before any orchestrator makes sense. Then we weigh the platform options against the team: Kubernetes offers the most flexibility and the most to operate, ECS and Cloud Run trade flexibility for a far smaller surface area. We also weigh managed control planes against self-hosted, cluster-per-environment against shared clusters with namespaces, and how much of the GitOps tooling the team will genuinely use.

Common failures in container platforms are quiet ones: a pod evicted for memory pressure because limits were guessed, a rolling update that passes health checks while the application is not actually ready, an image built from a floating tag that changes underneath you. We design against these with measured resource settings, readiness probes that check real dependencies, pinned base images with scheduled rebuilds, and disruption budgets that survive node maintenance. Handover includes the cluster configuration in version control, a runbook for scaling and upgrade scenarios, and a walkthrough in which your team performs a deployment, a rollback, and a node drain themselves.

  1. Scope it in writing

    What we agree before work starts

    • Production-grade Dockerfiles with multi-stage builds
    • Cluster or service setup (Kubernetes, ECS, or Cloud Run) with autoscaling
  2. Build with checkpoints

    Working results, not slide decks

    • GitOps deployment configuration with rollback
    • Resource sizing based on measured load
  3. Hand over something you own

    Documentation, source, and training

    • Runbook covering scaling, upgrades, and failure scenarios
    • Container image build pipeline with vulnerability scanning and pinned, regularly rebuilt base images

Sound familiar?

Where containerization & orchestration earns its keep.

An app that runs fine in staging and fails in production for reasons nobody can reproduce

A Kubernetes cluster inherited from a departed engineer that everyone is afraid to touch

A monolith moving to services that needs one consistent way to build and run them

Batch workloads burning money on servers that sit idle between runs

Common questions

Asked before every containerization & orchestration project.

Do we actually need Kubernetes?

Maybe not. Kubernetes is the right call when you have many services, multiple teams, or requirements like custom scheduling. For a handful of services, ECS or Cloud Run delivers most of the benefit with a fraction of the operational load. We are comfortable recommending the boring option.

Can you fix our existing cluster rather than rebuild it?

Usually, yes. Most troubled clusters suffer from a few compounding issues — missing resource limits, no pod disruption budgets, ad hoc manifests with no source of truth. We audit, stabilize, then bring the configuration under version control so it stops degrading.

How do you handle stateful workloads in containers?

Carefully and honestly. Databases and queues can run in orchestrators with persistent volumes and operators, but for many teams a managed database service is the better trade. We containerize what benefits from it and say so plainly when something should not be.

How do you keep container images secure and up to date?

Images are built in the pipeline from pinned base images, scanned for known vulnerabilities before they are pushed, and rebuilt on a schedule so operating-system patches flow through even when the application has not changed. We run containers as non-root users with minimal filesystems, and keep the registry tidy so it is clear which image is in production. None of this is exotic; the work is in making it automatic so it keeps happening after we leave.

Can you help with local development, not just production?

Yes, and it is often where the biggest daily gain is. The same images that run in production should run on a laptop with Docker Compose or a lightweight local cluster, with seeded data and hot reload where the language allows it. A consistent local environment removes a class of onboarding pain and makes the 'works on my machine' problem largely disappear, which is usually the point of containerizing in the first place.

Where this sits

Containerization & Orchestration, inside a cloud & infrastructure system.

The whole system this service belongs to. Hover or focus a component to see what it is and what it talks to.

Plant to cloud, and what watches itVPNMQTTSQLeventspushPlant networkTunnelVPN / private linkServicescontainersData storesDB, objectsMonitoringlogs, metricsOn-call

Hover or focus a component to see what it is and what it talks to. Arrow keys move between them.

Plant systems reach the cloud over an encrypted tunnel; services run in containers over managed data stores, and monitoring alerts a person before a customer notices.

Components:

  1. Plant network: OT network, segmented from IT.
  2. Tunnel (VPN / private link): Encrypted, allow-listed, no inbound ports on the plant side.
  3. Services (containers): Deployed from CI, rolled back in one command.
  4. Data stores (DB, objects): Managed database and object storage with backups tested, not assumed.
  5. Monitoring (logs, metrics): Health, latency, error rate, cost.
  6. On-call: Someone is paged before a customer emails.

Connections:

  • Plant network to Tunnel over VPN
  • Tunnel to Services over MQTT
  • Services to Data stores over SQL
  • Services to Monitoring over events
  • Monitoring to On-call over push
A typical architecture, drawn to explain the pattern — not a specific client's system.

Strategy. Software. Systems.

Have a system that should exist?

Tell us what your operation is doing manually, what isn't connected, or what you're trying to build. We'll tell you plainly whether and how we can help.