πŸ“œ Part of Pranav Kulkarni's technical portfolio Visit pranavkulkarni.org β†’
Lesson 1 Β· DevOps

Container Technologies

Master Docker and containerization for consistent deployments.

Containers package an application + its dependencies into a portable unit. They don’t virtualize hardware like VMs β€” they share the host kernel and rely on Linux primitives (namespaces + cgroups) for isolation and limits.

Docker Basics

Think in these objects: images (immutable templates) β†’ containers (running instances), plus volumes (data) and networks (connectivity).

$ docker run -d nginx # Run container
$ docker ps # List running
$ docker images # List images
$ docker pull nginx:latest # Pull image
$ docker exec -it container_id bash # Enter container
$ docker logs container_id # View logs
$ docker stop container_id # Stop container
$ docker rm container_id # Remove container
$ docker stats # CPU/mem per container

Volumes & Networking

Containers are ephemeral. Use volumes for persistent data and networks to connect services.

$ docker volume ls
$ docker network ls

# Run nginx and publish port 8080 on host
$ docker run -d -p 8080:80 --name web nginx

Dockerfile Example

A Dockerfile defines how to build an image. Good Dockerfiles are deterministic, cached efficiently, and produce small images.

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]

Build + tag + push (image lifecycle)

$ docker build -t myapp:1.0 .
$ docker tag myapp:1.0 registry.example.com/myapp:1.0
$ docker push registry.example.com/myapp:1.0

Production best practices

  • β€’Pin versions: avoid floating tags like latest for production
  • β€’Small images: use Alpine/distroless where appropriate; multi-stage builds
  • β€’Run as non-root: reduce blast radius of container compromise
  • β€’Secrets: never bake secrets into images; inject via env/secret stores
  • β€’Scanning: scan images for CVEs and keep base images updated

Docker Compose

Compose defines multi-container apps (web + db + cache) with networks and volumes. It’s the best way to run stacks locally.

$ docker-compose up -d
$ docker-compose down
$ docker-compose logs -f

βœ… Practice (30 minutes)

  • Run nginx on port 8080 (docker run -p 8080:80) and confirm with curl localhost:8080.
  • Build an image for a small app and compare image sizes before/after cleanup.
  • Use docker stats to observe container resource usage under load.