DevOps
Docker
Docker best practices for container build quality, security, and local developer workflows.
Docker
Docker is our baseline containerization tool for consistent local development, reproducible builds, and deployment packaging.
What it is
Docker packages applications and dependencies into portable container images that run consistently across environments.
Best practices
Why we use it
- Standardized runtime packaging across developer machines and environments.
- Predictable build/deploy artifacts.
- Strong ecosystem and tooling support.
Setup in this repo
- Use multi-stage builds for production images.
- Keep Dockerfiles close to services they package.
- Keep image tags/versioning aligned with CI outputs.
Team conventions
- Use slim base images and pin major versions.
- Keep layers cache-friendly by ordering stable steps first.
- Run processes as non-root where possible.
- Keep container startup deterministic and health-check friendly.
Error handling and reliability
- Fail build early when dependencies or required files are missing.
- Use explicit health checks for service readiness.
- Avoid mutable runtime assumptions in containers.
Testing and validation
- Validate images via local container run checks.
- Ensure startup, liveness/readiness, and env var behavior are tested.
- Scan images in CI for known vulnerabilities.
Abstractions and anti-patterns
- Avoid bloated images with unnecessary tools in production layers.
- Avoid mixing build-time and runtime concerns.
- Avoid unversioned base images in long-lived services.
Example
FROM node:20-alpine AS base
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
CMD ["node", "dist/main.js"]Common pitfalls
- Large images due to unnecessary files/dependencies.
- Slow rebuilds from poor layer ordering.
- Running apps as root in production containers.
- Missing health checks for orchestration systems.