World map

 

BM: Baca dalam Bahasa Melayu

World D4: Set Meals

Why a set meal?

You will learn: why one file can start your whole app.

Checked with Docker Engine 29 on 31 Oct 2026

The problem

Four long commands open the shop by hand: a phone line, then the database, the API and the web page, in that order. Docker transcript: $ docker network create kedai-net 01abe8096e6e2033e588c9e5fd44ec63959cff2f6ba501805ef61abf346b19a2 $ docker run -d --name db --network kedai-net -e POSTGRES_PASSWORD=example -v db-data:/var/lib/postgresql postgres:18-alpine 033291ed5c9e2b8b35d5ad227af13ccaa1195d555c6591b1f5e0564b6754c136 $ docker run -d --name api --network kedai-net -e DB_HOST=db kedai-api f616762aee3c4d180e7c85d19c30d3abf8db83fc996edee682504bc35bd1530c $ docker run -d --name web --network kedai-net -p 8080:80 kedai-web afb2e219cebc4aafef29bfe7aca4f7400096dbae25ec1c91607228c3ae70682e

Your laptop~/kedai-kancil

  • No open hatches

Lunchboxes (containers)

  • No containers yet

Frozen packs (images)

  • kedai-api:latest6 layers · 244MB
  • kedai-web:latest9 layers · 92.6MB
  • nginx:1.30-alpine8 layers · 93.5MB
  • node:24-alpine4 layers · 244MB
  • postgres:18-alpine9 layers · 433MB
  • redis:8-alpine7 layers · 162MB

0 containers (0 running), 6 images, 0 lockers.

Opening Kedai Kancil by hand takes four long commands. Every morning. In this order. Miss one flag, and the shop stays shut.

Watch

Read the file it wrote. Then press Order the set meal.

Menu (tap or drag)

Your set meal

  • web
    build: ./web
    Waits for
  • api
    build: ./api
    Waits for
  • db
    postgres:18-alpine
    Waits for

compose.yaml 17 lines

services:
web:
build: ./web
ports:
- "8080:80"
api:
build: ./api
environment:
DB_HOST: db
db:
image: postgres:18-alpine
environment:
POSTGRES_PASSWORD: example
volumes:
- db-data:/var/lib/postgresql
volumes:
db-data: {}

A set meal is ordered in one go. Compose: A set meal: start many containers together with one command. does that for containers. One file lists every dish. One order starts them all.

Watch

One command makes a phone line and a locker, then starts three lunchboxes: web, api and db. Docker transcript: $ docker compose up -d [+] up 5/5 ✔ Network kedai-kancil_default Created 0.1s ✔ Volume kedai-kancil_db-data Created 0.0s ✔ Container kedai-kancil-web-1 Started 0.3s ✔ Container kedai-kancil-api-1 Started 0.3s ✔ Container kedai-kancil-db-1 Started 0.3s $ docker compose ps NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS kedai-kancil-api-1 kedai-kancil-api "docker-entrypoint.s…" api 3 seconds ago Up 3 seconds 3000/tcp kedai-kancil-db-1 postgres:18-alpine "docker-entrypoint.s…" db 3 seconds ago Up 3 seconds 5432/tcp kedai-kancil-web-1 kedai-kancil-web "/docker-entrypoint.…" web 3 seconds ago Up 3 seconds 0.0.0.0:8080->80/tcp

Your laptop~/kedai-kancil

  • No open hatches

Lunchboxes (containers)

  • No containers yet

Frozen packs (images)

  • kedai-kancil-api:latest6 layers · 244MB
  • kedai-kancil-web:latest9 layers · 92.6MB
  • nginx:1.30-alpine8 layers · 93.5MB
  • node:24-alpine4 layers · 244MB
  • postgres:18-alpine9 layers · 433MB
  • redis:8-alpine7 layers · 162MB

0 containers (0 running), 6 images, 0 lockers.

That is the real thing. docker compose up -d reads compose.yaml and starts every dish in the background.

Try it

Your turn. Start the whole shop with one command. Then knock on hatch 8080 with curl localhost:8080.

Your laptop~/kedai-kancil

  • No open hatches

Lunchboxes (containers)

  • No containers yet

Frozen packs (images)

  • kedai-kancil-api:latest6 layers · 244MB
  • kedai-kancil-web:latest9 layers · 92.6MB
  • nginx:1.30-alpine8 layers · 93.5MB
  • node:24-alpine4 layers · 244MB
  • postgres:18-alpine9 layers · 433MB
  • redis:8-alpine7 layers · 162MB

0 containers (0 running), 6 images, 0 lockers.

Check

Which tool fits each job?

Drag a card into a box. Or tap the card, then tap the box.

        You did it!

        You can now start a whole stack with one command.

        Go deeper (optional)

        docker compose is a plugin for the docker command. It looks for compose.yaml in your folder. The folder name becomes the project name. That is why the boxes are called kedai-kancil-web-1.

        Real rep (optional), on your own machine:

        Real mission

        1. mkdir hello-set && cd hello-set
        2. printf 'services:\n web:\n image: nginx:1.30-alpine\n ports:\n - "8080:80"\n' > compose.yaml
        3. docker compose up -d
        4. docker compose down

        0 of 5 steps done · Your ticks are saved.