Backend6 min read

Docker

Package applications and dependencies into portable containers - ensuring consistent environments from development through production.

DockerContainersDockerfileDocker ComposeDevOps

skill: Docker category: Backend tags: [Docker, Containers, Dockerfile, Docker Compose, DevOps] readingTime: 6

Docker is the standard containerization tool - if your app runs in Docker, it runs the same everywhere. Use Docker for local development parity, CI builds, and production deployment. For orchestration at scale, pair with Kubernetes.

Workflow

  1. Write a DockerfileA Dockerfile is a reproducible recipe for building your app image - base image, dependencies, code, and runtime command.
  2. Optimize image sizeSmaller images pull faster, start faster, and have a smaller attack surface. Alpine base images are 5MB vs 900MB for the full Debian-based node.
  3. Compose services locally with docker-composeDocker Compose runs multiple containers (app + DB + Redis) locally with a single command - eliminating 'install Postgres on your machine' setup docs.
  4. Run securely with a non-root userBy default, containers run as root - if the container is compromised, the attacker has root access to the container. Always run as a non-root user.
  5. Tag, push, and pull from a registryDocker registries (Docker Hub, GHCR, ECR) store and distribute images for deployment to any server or Kubernetes cluster.

Output Format

Production Docker image: Alpine base, multi-stage build, non-root user, optimized layers.

project/
├── Dockerfile          # Multi-stage production build
├── .dockerignore       # Exclude node_modules, .git, etc.
├── docker-compose.yml  # Local dev: app + db + redis
└── docker-compose.prod.yml # Production overrides

Examples

Input

Output

Edge Cases & Gotchas

  • Secrets in Dockerfile or images - Never ARG or ENV a secret in the Dockerfile - it's stored in image layers. Use Docker secrets, runtime environment variables, or a secrets manager at startup.
  • Volume mounts override COPY - A bind mount from docker-compose (-v ./src:/app/src) overlays the container's filesystem. If the local dir is empty, it hides the container's files.
  • PID 1 and signal handling - Node.js as PID 1 doesn't handle SIGTERM correctly by default. Use ENTRYPOINT ["/usr/bin/tini", "--"] with Tini as init, or node --enable-source-maps as a proper PID 1.
  • File permissions between host and container - Files created by a non-root container user may not be writable by the host user and vice versa. Match UIDs: --user $(id -u):$(id -g) in docker run.

When to Break These Rules

  • Use Podman instead of Docker for rootless containers and daemonless operation in security-sensitive or RHEL/Fedora environments.
  • Use nix or devcontainers for development environments when reproducibility of the entire toolchain (not just runtime) is required.

Reference Files

  • https://docs.docker.com/
  • https://docs.docker.com/compose/

More skills in this library

Browse all technical skills - Mobile, AI/ML, Web, Backend, Design, and Product.