Skip to content
back to the map
technique
stage: foundations
2 min read

Containers and images

A container packages an application with its dependencies and runs it isolated from the host. A good image is small, deterministic and runs as a non-root user.

Docker / PodmanBuildKitTrivyHadolintDivecontainer registries

How containers work

  • A container is a normal Linux process with its own view of the filesystem, network and process table (namespaces) and limited resources (cgroups). It shares the host kernel, unlike a virtual machine.
  • An image is a stack of read-only layers plus metadata. A container adds a thin writable layer on top.
  • A registry stores images by name and tag; a digest (sha256) identifies exact content and never changes.
  • Containers are meant to be disposable: state lives in volumes, databases or object storage, not inside the container.

A weak Dockerfile

Problems: a floating tag changes without notice, the whole directory (including .git and .env) is copied, dev dependencies and build tools ship to production, no layer caching, and the process runs as root.

Dockerfile (before)dockerfile
FROM node:latest
COPY . .
RUN npm install
EXPOSE 3000
CMD ["node", "server.js"]

A better one

Use a pinned base, a multi-stage build, a lockfile install, a non-root user and an ignore file.

Dockerfile (after)dockerfile
# build stage: has the compilers and dev dependencies
FROM node:22-slim@sha256:<digest-you-reviewed> AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build && npm prune --omit=dev

# runtime stage: only what the app needs
FROM node:22-slim@sha256:<digest-you-reviewed>
ENV NODE_ENV=production
WORKDIR /app
COPY --from=build --chown=node:node /app/dist ./dist
COPY --from=build --chown=node:node /app/node_modules ./node_modules
USER node
EXPOSE 3000
HEALTHCHECK CMD node -e "fetch('http://localhost:3000/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
CMD ["node", "dist/server.js"]
.dockerignoretext
.git
node_modules
.env
*.log
coverage

Habits

  • Rebuild and redeploy regularly: images do not patch themselves.
  • Scan images in CI and fail on serious findings you can fix.
  • One process per container, logs to stdout, configuration through the environment or mounted files.
  • Tag with the commit and deploy by digest so a rollback is exact.
  • Keep images small: fewer packages, fewer vulnerabilities, faster pulls.

connections on the map

updated on 14/10/2026 · sources to go deeper · report an error

in other domains

Study before

Unlocks

test what you learned

Loading questions…