Skip to main content

What is Docker

Docker is a tool that packages an application together with everything it needs to run—code, runtime, system libraries, and configuration—into a container.

A container runs the same way on any machine with Docker installed. This removes “works on my machine” problems and makes development, testing, and deployment more predictable.


Why use Docker?

  • Reproducible development environments
  • Easy deployment across machines and clouds
  • Isolation between projects (no dependency conflicts)
  • Faster onboarding and CI/CD pipelines

Core concepts (explained simply)

  • Image A read-only blueprint for an application. Built once, reused many times.

  • Container A running instance of an image. Containers are isolated processes.

  • Dockerfile A text file that defines how an image is built (base image, files, commands).

  • Layers Images are built in layers. Docker caches layers to speed up rebuilds.

  • Volumes Persistent storage that survives container restarts and removal.

  • Networking Containers can expose ports and communicate over private networks.

tip

An image is static. A container is running. You build images and run containers.


Step-by-step example

Minimal Node.js app

Dockerfile

FROM node:18-slim
WORKDIR /app
COPY app.js .
EXPOSE 3000
CMD ["node", "app.js"]

app.js

require("http")
.createServer((_, res) => res.end("Hello from Docker"))
.listen(3000);

Build and run

docker build -t hello-docker .
docker run -d -p 3000:3000 --name hello hello-docker

Check status and logs:

docker ps
docker logs hello

Stop and remove:

docker stop hello && docker rm hello

Useful everyday commands

  • List containers: docker ps -a
  • Enter a container shell: docker exec -it <name> sh
  • Run interactively: docker run -it <image> bash
  • Remove unused data: docker system prune

Common pitfalls

  • Forgetting .dockerignore → slow builds, huge images
  • Using latest tags in production
  • Storing data inside the container instead of volumes
  • Baking secrets into images
  • Exposing ports unnecessarily

Best practices

  • Use small base images (slim, alpine when possible)
  • Pin image versions
  • Use multi-stage builds for production
  • Run containers as non-root users
  • Use environment variables or secret stores
  • Add health checks for long-running services

When to use Docker

  • Local development parity with production
  • CI/CD pipelines
  • Multi-service apps (API + DB + cache)
  • Moving to a PaaS or Kubernetes later

When not to use Docker

  • Apps requiring custom kernel modules
  • Extremely simple scripts where Docker adds overhead
  • Hardware-bound workloads without container support

Key takeaways

  • Docker standardizes how applications are built and run
  • Images are templates; containers are running processes
  • Dockerfiles define reproducible builds
  • Volumes handle persistent data
  • Docker Compose manages multi-service setups

Next steps