Skip to main content

Containers

Container and Kubernetes best practices

6
Best Practices
1
Stacks
11
FAQs
1
Benchmarks

Best Practices

CNCF Cloud-Native Definition & Principles

The CNCF’s formal definition of cloud-native computing and core principles for micro-services, containers, and dynamic orchestration.

by Cloud Native Computing Foundation

Kubernetes Pod Security Standards

Baseline, restricted, and privileged policy levels for securing pod workloads.

by Kubernetes SIG Auth

CNCF Cloud-Native Security Whitepaper

Guidance on building, shipping, and running secure cloud-native applications.

by CNCF Security TAG

Helm Chart Best Practices

Recommendations for structure, naming, versioning, and values of Helm charts.

by Helm Maintainers

Container Image Hardening Guide

Steps to build minimal, non-root, signed container images with SBOMs.

by CIS & Docker

Sidecar Pattern

A design pattern that deploys a helper component alongside the main application in the same unit, adding capabilities like proxying, logging, or config without changing the app.

by Microsoft

Tutorials

How to build and optimize Docker images for smaller, faster builds

Reduce Docker image size and build time with layer ordering, .dockerignore, and build cache strategies.

How to use multi-stage Docker builds to shrink production images

Separate build and runtime stages so compilers and dev dependencies stay out of the final image.

How to build distroless container images for minimal attack surface

Run applications on distroless base images that contain no shell or package manager, reducing size and CVEs.

How to run a multi-container app with Docker Compose

Define an app, a database, and a cache as services in one Compose file with networks, volumes, and health checks.

How to deploy an application to Kubernetes with Deployment and Service

Package an image into a Kubernetes Deployment and expose it with a Service, then scale and roll out updates.

How to configure liveness, readiness, and startup probes in Kubernetes

Add health probes so Kubernetes restarts unhealthy pods and only routes traffic to ready ones.

How to autoscale pods with the Kubernetes HorizontalPodAutoscaler

Scale a Deployment automatically on CPU or custom metrics using the HorizontalPodAutoscaler and metrics-server.

How to expose Kubernetes services with an Ingress and TLS

Route external HTTP traffic to services using an Ingress controller, host and path rules, and automatic TLS.

How to manage configuration with Kubernetes ConfigMaps and Secrets

Externalize app settings into ConfigMaps and sensitive values into Secrets, mounted as env vars or files.

How to run stateful workloads with a Kubernetes StatefulSet

Deploy databases and other stateful apps with stable network identities and per-pod persistent storage.

How to build and run rootless containers

Run containers as a non-root user with Podman or Docker rootless mode to reduce privilege and risk.

How to set Kubernetes resource requests and limits correctly

Right-size CPU and memory requests and limits to improve scheduling, stability, and Quality of Service.

Checklists

Kubernetes Production Readiness Checklist

Confirm a Kubernetes cluster and its workloads are secure, observable, and resilient before serving production traffic.

Container Security Hardening Checklist

Harden container images, build pipelines, and runtime so containerized workloads resist compromise and supply-chain attacks.

Kubernetes Cluster Setup Checklist

Provision a new managed Kubernetes cluster with the networking, security, and platform add-ons teams need from day one.

Technology Stacks

AWS ECS Fargate Containers Stack

Managed container stack running Docker workloads on AWS ECS with Fargate serverless compute, behind a load balancer, without managing servers or clusters.

FAQs

What is a container?

A container is a lightweight, standalone unit that packages an application together with its dependencies, libraries, and configuration so it runs consistently across environments. Containers share the host operating system kernel and isolate processes using OS features such as namespaces and cgroups, which makes them far smaller and faster to start than virtual machines. They are the standard way to build, ship, and run cloud-native applications. Docker popularized the format, and the Open Container Initiative (OCI) now defines the image and runtime standards.

What is the difference between a Docker container and a virtual machine?

A virtual machine (VM) virtualizes hardware and runs a full guest operating system on top of a hypervisor, so each VM carries its own kernel and is heavy in size and boot time. A container virtualizes the operating system instead, sharing the host kernel and isolating only the application and its dependencies, which makes it megabytes rather than gigabytes and starts in seconds. VMs offer stronger isolation and can run different operating systems, while containers offer higher density and faster deployment. Many production systems combine both, running containers inside VMs for layered isolation.

What is Kubernetes?

Kubernetes is an open-source platform for automating the deployment, scaling, and operation of containerized applications. It groups containers into logical units, schedules them across a cluster of machines, restarts failed workloads, and rolls out updates without downtime. Originally developed at Google and now governed by the Cloud Native Computing Foundation (CNCF), it has become the de facto standard for container orchestration. Users describe the desired state in declarative manifests, and Kubernetes continuously reconciles the actual state to match it.

What is the difference between a Kubernetes pod and a container?

A container is a single packaged process, while a pod is the smallest deployable unit in Kubernetes and can hold one or more containers that share the same network namespace and storage volumes. Containers in a pod are always scheduled together on the same node and can communicate over localhost. Most pods run a single primary container, but a pod may include helper containers such as sidecars or init containers. Kubernetes manages pods, not individual containers, when scaling and scheduling.

When should I use Kubernetes?

Kubernetes makes sense when you run many containerized services that need automated scaling, self-healing, rolling updates, and consistent deployment across environments. It is a strong fit for microservice architectures, multi-team platforms, and workloads with variable load. For a single small application or a simple website, Kubernetes often adds unnecessary operational complexity, and a managed container service, platform-as-a-service, or serverless option may be simpler. The decision should weigh the operational cost of running Kubernetes against the scale and flexibility you actually need.

What is a Kubernetes ingress controller?

An ingress controller is a component that implements Kubernetes Ingress resources, routing external HTTP and HTTPS traffic to services inside the cluster based on rules such as hostnames and URL paths. The Ingress object defines the routing rules, but a controller, such as NGINX, Traefik, or a cloud load-balancer integration, must be installed to enforce them. Ingress controllers commonly handle TLS termination, name-based virtual hosting, and path-based routing. They provide a single, centralized entry point instead of exposing each service separately.

What is a container image?

A container image is a read-only template that contains everything needed to run an application: code, runtime, libraries, environment variables, and configuration. Images are built in layers, where each instruction adds a layer that can be cached and shared, making builds and distribution efficient. When you run an image, the container engine adds a writable layer on top to create a running container. Images follow the Open Container Initiative (OCI) standard and are stored in registries such as Docker Hub or a private registry.

What is a container registry?

A container registry is a storage and distribution system for container images, allowing them to be pushed after a build and pulled at deployment time. Public registries such as Docker Hub host shared images, while private registries such as Amazon ECR, Google Artifact Registry, Azure Container Registry, and Harbor host an organization's own images. Registries support versioning through tags and digests and often add features like vulnerability scanning, access control, and image signing. They are a core part of any container delivery pipeline.

What is container orchestration?

Container orchestration is the automated management of the lifecycle of containers across a cluster of machines, including scheduling, scaling, networking, load balancing, and self-healing. As the number of containers grows, manual management becomes impractical, and an orchestrator handles placement, restarts failed containers, and rolls out updates safely. Kubernetes is the dominant orchestrator, with alternatives such as Docker Swarm, HashiCorp Nomad, and managed services like Amazon ECS. Orchestration is what makes large-scale containerized systems operable and reliable.

What is a Kubernetes namespace?

A namespace is a way to divide a single Kubernetes cluster into multiple virtual clusters, providing a scope for names and a boundary for resources. Namespaces let teams or environments such as development, staging, and production share one cluster while keeping their objects logically separated. They enable resource quotas, access control through role-based policies, and network policies to be applied per group. Namespaces provide logical isolation but not strong security isolation between workloads on their own.

What is a Kubernetes service?

A Kubernetes Service is an abstraction that gives a stable network identity and address to a dynamic set of pods, since pods are ephemeral and their IP addresses change. It load-balances traffic across the matching pods using label selectors, so clients connect to the service rather than to individual pods. Common types are ClusterIP for internal access, NodePort and LoadBalancer for external access, and ExternalName for mapping to an external host. Services are how reliable communication between components is achieved inside a cluster.

Benchmarks

Container Startup Time Benchmark

Measures how quickly a container goes from launch to ready, covering image pull, runtime creation, and application readiness for scaling and resilience.

Vibgrate CLI

See a real scan run

A replay of the actual CLI running against our test repositories — live progress, real findings, a genuine DriftScore. Nothing executes in your browser.

Replay
demo@vibgrate — bash
npx @vibgrate/cli scan
 
╭──────────────────────────────────────────╮
Vibgrate Drift Report
╰──────────────────────────────────────────╯
 
── node-turborepo (node) .
Runtime: >=18.0.0 (6 majors behind)
Frameworks:
Turbo: 1.13.4 → 2.10.12 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
1 current 1 1-behind 3 2+ behind 1 unknown
 
── @repo/admin (node) apps/admin
Frameworks:
TanStack Query: 5.102.5 → 5.102.5 (current)
React: 18.3.1 → 19.2.8 (1 behind)
React DOM: 18.3.1 → 19.2.8 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Vite: 5.4.21 → 8.2.2 (3 behind)
Dependencies:
3 current 9 1-behind 3 2+ behind 4 unknown
 
── @repo/api (node) apps/api
Frameworks:
Express: 4.22.2 → 5.2.1 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Vitest: 1.6.1 → 4.1.11 (3 behind)
Dependencies:
7 current 5 1-behind 3 2+ behind 4 unknown
 
── @repo/web (node) apps/web
Frameworks:
Next.js: 14.2.35 → 16.3.3 (2 behind)
React: 18.3.1 → 19.2.8 (1 behind)
React DOM: 18.3.1 → 19.2.8 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
2 current 6 1-behind 3 2+ behind 5 unknown
 
── @repo/config (node) packages/config
Frameworks:
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
2 current 2 1-behind 5 2+ behind 0 unknown
 
── @repo/database (node) packages/database
Frameworks:
Prisma: 5.22.0 → 7.10.0 (2 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
1 current 0 1-behind 3 2+ behind 1 unknown
 
── @repo/types (node) packages/types
Frameworks:
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Dependencies:
0 current 0 1-behind 1 2+ behind 1 unknown
 
── @repo/ui (node) packages/ui
Frameworks:
React: 18.3.1 → 19.2.8 (1 behind)
TypeScript: 5.9.3 → 7.0.2 (2 behind)
React: 18.3.1 → 19.2.8 (1 behind)
Dependencies:
1 current 4 1-behind 1 2+ behind 1 unknown
 
── @repo/utils (node) packages/utils
Frameworks:
TypeScript: 5.9.3 → 7.0.2 (2 behind)
Vitest: 1.6.1 → 4.1.11 (3 behind)
Dependencies:
0 current 1 1-behind 2 2+ behind 1 unknown
 
Tech Stack
Frontend: React, React DOM
Meta-frameworks: Next.js
Bundlers: tsx, Turbo, Vite
CSS / UI: Autoprefixer, PostCSS, Tailwind CSS
Backend: Express
ORM / Database: Prisma, Prisma Client
Testing: Vitest
Lint & Format: ESLint, ESLint Prettier, ESLint React, Prettier, typescript-eslint
 
Services & Integrations
Auth: JWT 9.0.3
Databases: Prisma 5.22.0
 
TypeScript
v5.3.3 · strict ✔ · MIXED · target: ES2022
 
Build & Deploy
Package Managers: pnpm
Monorepo: npm-workspaces, pnpm-workspaces, turbo
 
Product Purpose Signals
Frameworks: react, nextjs
Evidence: 177
Top Signals:
- [heading] Dashboard (apps/admin/src/pages/Dashboard.tsx)
- [title] Revenue Overview (apps/admin/src/pages/Dashboard.tsx)
- [copy] workspace:* (packages/ui/package.json)
- [copy] ./dist (packages/ui/tsconfig.json)
- [copy] ./src/index.ts (packages/ui/package.json)
- [copy] @repo/config/tsconfig-base.json (packages/ui/tsconfig.json)
- [copy] @repo/ui (packages/ui/package.json)
- [copy] #3b82f6 (apps/admin/src/pages/Dashboard.tsx)
Unknowns:
- No pricing or billing evidence found.
- No integrations/connectors evidence found.
- No route structure evidence found.
 
Security Posture
Lockfile ✖ · .env ✔ · node_modules ✔
 
Platform
Native modules: turbo
 
Code Quality
Files: 36 · Functions: 183 · Avg complexity: 2.62 · Avg length: 21.13 lines
Max nesting: 2 · Circular deps: 0 · Dead code: 0%
God files: apps/admin/src/pages/Products (448 lines)
 
Database Schema
postgresql · 8 models · 1 enum
Models: Address, CartItem, Category, Order, OrderItem (+3 more)
 
Findings (16 errors, 11 warnings)
Node.js runtime ">=18.0.0" reached end-of-life on 2025-04-30 (latest: 24.0.0).
vibgrate/runtime-eol in .
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in .
60% of dependencies are 2+ major versions behind in node-turborepo.
vibgrate/dependency-rot in .
@types/node is 6 major versions behind (spec: ^20.11.0, latest: 26.3.0).
vibgrate/dependency-major-lag in .
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in apps/admin
Vite is 3 major versions behind (current: 5.4.21, latest: 8.2.2).
vibgrate/framework-major-lag in apps/admin
vite is 3 major versions behind (spec: ^5.0.12, latest: 8.2.2).
vibgrate/dependency-major-lag in apps/admin
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in apps/api
Vitest is 3 major versions behind (current: 1.6.1, latest: 4.1.11).
vibgrate/framework-major-lag in apps/api
@types/node is 6 major versions behind (spec: ^20.11.0, latest: 26.3.0).
vibgrate/dependency-major-lag in apps/api
vitest is 3 major versions behind (spec: ^1.2.1, latest: 4.1.11).
vibgrate/dependency-major-lag in apps/api
Next.js is 2 major versions behind (current: 14.2.35, latest: 16.3.3).
vibgrate/framework-major-lag in apps/web
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in apps/web
@types/node is 6 major versions behind (spec: ^20.11.0, latest: 26.3.0).
vibgrate/dependency-major-lag in apps/web
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/config
56% of dependencies are 2+ major versions behind in @repo/config.
vibgrate/dependency-rot in packages/config
eslint-plugin-react-hooks is 3 major versions behind (spec: ^4.6.0, latest: 7.1.1).
vibgrate/dependency-major-lag in packages/config
Prisma is 2 major versions behind (current: 5.22.0, latest: 7.10.0).
vibgrate/framework-major-lag in packages/database
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/database
75% of dependencies are 2+ major versions behind in @repo/database.
vibgrate/dependency-rot in packages/database
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/types
100% of dependencies are 2+ major versions behind in @repo/types.
vibgrate/dependency-rot in packages/types
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/ui
TypeScript is 2 major versions behind (current: 5.9.3, latest: 7.0.2).
vibgrate/framework-major-lag in packages/utils
Vitest is 3 major versions behind (current: 1.6.1, latest: 4.1.11).
vibgrate/framework-major-lag in packages/utils
67% of dependencies are 2+ major versions behind in @repo/utils.
vibgrate/dependency-rot in packages/utils
vitest is 3 major versions behind (spec: ^1.2.1, latest: 4.1.11).
vibgrate/dependency-major-lag in packages/utils
 
╭──────────────────────────────────────────╮
Top Priority Actions
╰──────────────────────────────────────────╯
 
1. Upgrade EOL runtime in node-turborepo
End-of-life runtimes no longer receive security patches and block ecosystem upgrades.
./.
>=18.0.0 → 24.0.0 (6 majors behind)
Impact: −10 drift points (runtime & EOL)
 
2. Fix security posture: no lockfile found
Without a lockfile, installs are non-deterministic. Run the install command to generate one and commit it.
./
Missing: package-lock.json, pnpm-lock.yaml, or yarn.lock
 
3. Upgrade Vite 5.4.21 → 8.2.2 in @repo/admin (+2 more)
3 major versions behind. Major framework drift increases breaking change risk and blocks access to security fixes and performance improvements.
./apps/admin
Vite: 5.4.21 → 8.2.2 (3 majors behind)
./apps/api
Vitest: 1.6.1 → 4.1.11 (3 majors behind)
./packages/utils
Vitest: 1.6.1 → 4.1.11 (3 majors behind)
Impact: −5–15 drift points
 
4. Reduce dependency rot in @repo/types (100% severely outdated)
1 of 1 dependencies are 2+ majors behind. Run `npm outdated` and prioritise packages with known CVEs or breaking API changes.
./packages/types
typescript: 5.9.3 → 7.0.2 (2 majors behind)
Impact: −5–10 drift points
 
5. Reduce dependency rot in @repo/database (75% severely outdated)
3 of 4 dependencies are 2+ majors behind. Run `npm outdated` and prioritise packages with known CVEs or breaking API changes.
./packages/database
@prisma/client: 5.22.0 → 7.10.0 (2 majors behind)
prisma: 5.22.0 → 7.10.0 (2 majors behind)
typescript: 5.9.3 → 7.0.2 (2 majors behind)
Impact: −5–10 drift points
 
╭──────────────────────────────────────────╮
Architecture Layers
╰──────────────────────────────────────────╯
 
Archetype: nextjs (80% confidence)
Files classified: 24 (11 unclassified)
Folders classified: 8
apps/admin/src presentation 100% 4 files
apps/admin/src/pages presentation 100% 2 files
apps/api/src/middleware middleware 100% 2 files
apps/api/src/routes routing 100% 2 files
apps/web/src/app presentation 100% 4 files
apps/web/src/app/products presentation 100% 2 files
apps/web/src/app/products/[id] presentation 100% 1 file
packages/ui/src presentation 100% 6 files
Unclassified source (sample): 11
 
presentation 15 files drift ████████████████████ 100 risk high
routing 4 files drift ████████████████████ 100 risk high
middleware 2 files drift ███████▍░░░░░░░░░░░░ 37 risk moderate
config 2 files drift ░░░░░░░░░░░░░░░░░░░░ 0 risk none
shared 1 file drift ████████████████████ 100 risk high
 
╭──────────────────────────────────────────╮
DriftScore Summary
╰──────────────────────────────────────────╯
 
DriftScore: 66/100
Risk Level: HIGH
Projects: 9
Classified: 8 nano · 1 micro · 0 small · 0 standard
Billable: 0.42 · 9 detected → 0.42 billable projects (micro-project pricing)
0.1 micro · 0.32 nano
These fractions add up across repositories, then round down to whole billable projects.
 
Score Breakdown
Runtime: ████████████████████ 100
Frameworks: █████████▏░░░░░░░░░░ 46
Dependencies: ██████▏░░░░░░░░░░░░░ 31
EOL Risk: ████████████████████ 100
 
Scanned at 2026-08-26T09:08:28.481Z · 7.1s · 286 files scanned · 56 workspace files · 27 dirs
Press Run to start.