Fullstack CourseLearn by building
Back to week 4

Topic

Docker & Compose

Definition

A container packages an application with its runtime dependencies into an isolated, reproducible unit, while a multi-container orchestration file such as docker-compose.yml declares how several related containers, such as an API, database, cache, and broker, run and network together.

In simpler words

Docker ships this exact app plus everything it needs as one predictable box. Compose wires several boxes together for local development.

Judge Docker the same conceptual way as Redis or RabbitMQ: where it solves a real environment problem, and where it stops mattering for this course.

After this you can

  • Explain what a container isolates versus a virtual machine
  • Read a docker-compose.yml and name each service role
  • Reason about why it works on my machine gets fixed by containers
  • Describe the tradeoff of adding Docker to a small team workflow

Why containers instead of installing locally

Definition

Environment drift occurs when developer machines have different tool, library, or operating system versions than production, producing bugs that only reproduce on some machines. Containers eliminate that drift by shipping the exact runtime.

In simpler words

Docker stops it works on my laptop but not in staging by shipping the whole environment, not only the code.

A container bundles the app, its language runtime, and system libraries into one image that runs identically on a laptop, a CI runner, or a production host.

Compared to a full virtual machine, a container shares the host kernel and starts in seconds, which is why local development stacks combining a database, cache, broker, and API commonly run as containers instead of virtual machines.

A typical setup runs Postgres in a container for local development specifically so every contributor gets the same database version without installing Postgres natively.

Reading a compose file

services:
  api:
    build: ./apps/api
    ports: ["3001:3001"]
    depends_on: [postgres, redis]
  postgres:
    image: postgres:16
    environment: { POSTGRES_PASSWORD: dev }
  redis:
    image: redis:7

Each service is one container. depends_on only orders startup; it does not wait for the database to accept connections.

What Compose does and does not guarantee

Definition

docker-compose.yml declares service definitions, networking, and startup order for local or single-host multi-container environments. It does not manage rolling deploys, autoscaling, or multi-host orchestration.

In simpler words

Compose is great for running a whole stack locally with one command. It is not a production deployment platform by itself.

depends_on controls container start order, not application readiness. Nest must still retry its Postgres connection on boot rather than assume the database is already accepting queries.

Named volumes persist data, such as a Postgres data directory, across container restarts. Without one, stopping the stack can silently wipe local development data.

Production-grade orchestration, such as rolling updates, health-based routing, and scaling, is typically a separate tool such as Kubernetes or a managed container service. Compose is the local development and single-host layer.

Keep in mind

  • Containers fix environment drift; they do not fix incorrect code.
  • depends_on is start order, not a readiness check, so code defensively.
  • Reach for full orchestration only once the single-host model of Compose is not enough.

Test

Check your understanding

At least 10 questions — mix of concept, syntax, practical, and logic. Score ≥80% (enforced by the API) to save progress.

Checking your session…

15 questions · concept 5 · syntax 3 · practical 4 · logic 3

1. What does Compose buy you?
Concept
2. Where should secrets live?
Syntax
3. Do containers replace migrations?
Practical
4. Does Docker remove Nest structure needs?
Logic
5. What should a good API Dockerfile do?
Concept
6. Why depend_on Postgres in Compose?
Practical
7. What about binding Postgres data?
Syntax
8. Is synchronize true OK only in containers?
Logic
9. How do services find each other in Compose?
Concept
10. Which practice is wrong?
Practical
11. Why is this Dockerfile practice bad?
Conceptadvanced
# Dockerfile
COPY .env.production .env
12. What is postgres in the host part of this URL?
Syntaxintermediate
# docker-compose.yml
services:
  api:
    environment:
      DATABASE_URL: postgres://user:pass@postgres:5432/app
13. What does depends_on guarantee here?
Practicaladvanced
services:
  api:
    depends_on:
      - postgres
14. What does this bind mount achieve?
Logicintermediate
services:
  postgres:
    volumes:
      - ./data/postgres:/var/lib/postgresql/data
15. What step is missing before the app serves traffic?
Conceptadvanced
# entrypoint
node dist/main.js  # synchronize:false

Checking your session…