Career OS

Week 9 — Docker: Package Your App Like a Pro

The full Docker track is now live

This week is the schedule. The depth lives in the Docker track — 9 modules from “what a container actually is” through images & layers, the build cache, writing a real Dockerfile, running containers, volumes & networking, Compose, registries, and a containerize-SplitEase capstone, with interactive visualizers. Use the days below as the timetable and learn each topic from the matching module: Day 1 → Docker 01, Day 2 → Docker 03, Day 3 → Docker 06, Day 4–5 → Cloud: Deploying.

Why Docker Matters

“It works on my machine” is the most useless sentence in software engineering. Docker ensures your app runs the same everywhere — your laptop, CI server, production.

Daily Breakdown

Day 1: Docker Fundamentals — What Containers Actually Are

Containers are NOT virtual machines.

VMContainer
IsolationFull OS per VMShares host OS kernel
SizeGigabytesMegabytes
StartupMinutesSeconds
OverheadHigh (each VM runs full OS)Low (just your app + dependencies)
Use caseFull isolation neededApplication packaging

Key concepts:

  • Image: Blueprint. Read-only. “A snapshot of everything needed to run your app.”
  • Container: Running instance of an image. Has its own filesystem, network, processes.
  • Dockerfile: Recipe to build an image.
  • Layer: Each instruction in Dockerfile creates a layer. Layers are cached.

Day 2: Dockerize Your Spring Boot App

# Multi-stage build — keeps final image small
FROM eclipse-temurin:21-jdk-alpine AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
# Download dependencies first (cached if pom.xml doesn't change)
RUN ./mvnw dependency:resolve
RUN ./mvnw package -DskipTests

FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar

# Don't run as root in production
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

Why multi-stage? The build stage has Maven, source code, all build tools (~800MB). The final image only has the JRE and your JAR (~200MB). Smaller = faster deploys.

Day 3: Docker Compose — Multi-Container Setup

# docker-compose.yml
services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/splitwise
      - SPRING_DATASOURCE_USERNAME=postgres
      - SPRING_DATASOURCE_PASSWORD=postgres
      - SPRING_REDIS_HOST=redis
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    
  db:
    image: postgres:16-alpine
    environment:
      - POSTGRES_DB=splitwise
      - POSTGRES_PASSWORD=postgres
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  pgdata:

Run: docker compose up --build

Your entire stack — app, database, Redis — starts with one command. Anyone can clone your repo and run it.

Day 4: Deploy to Free Cloud

Options (all have free tiers):

ServiceFree TierBest For
Railway$5 free credit/monthEasiest. Docker deploy from GitHub.
Render750 hours/monthGood for web services + PostgreSQL
Fly.io3 shared VMsDocker-native, global deployment

Deploy to Railway (simplest):

  1. Push your code to GitHub
  2. Connect Railway to your GitHub repo
  3. Railway detects Dockerfile, builds, deploys
  4. Get a public URL: your-app.up.railway.app

Set up environment variables in Railway dashboard (not in code!):

  • DATABASE_URL — Railway provides a PostgreSQL add-on
  • REDIS_URL — Railway Redis add-on
  • JWT_SECRET — generate a random 256-bit key

Day 5: Test Your Deployed API

# Test health
curl https://your-app.up.railway.app/actuator/health

# Register a user
curl -X POST https://your-app.up.railway.app/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com","password":"Test@123","name":"Test User"}'

# Login
curl -X POST https://your-app.up.railway.app/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com","password":"Test@123"}'

Your API is now live on the internet. Put this URL on your resume.

Weekend: DSA + Docker Deep Dive

  • Understand Docker networking (how containers talk to each other)
  • Understand volumes (how data persists when containers restart)
  • DSA: DSA 07 — Linked Lists — module + 5 problems from its list

Resources

WhatWhereTime
Docker in 5 minDocker official “Get Started”30 min
Multi-stage buildsDocker docs “Multi-stage builds”15 min
Docker ComposeDocker docs “Compose Getting Started”20 min
Railway deployrailway.app docs15 min