World map

 

BM: Baca dalam Bahasa Melayu

World D2: Recipes

Your first recipe: FROM, COPY, CMD

You will learn: to write a three-line Dockerfile and bake it into an image.

Checked with Docker Engine 29 on 31 Oct 2026

The problem

Your hello app works on your laptop. On Aina’s laptop it crashes. She has an older Node. What fixes this for good?

Pick one answer.

Watch

cat shows a Dockerfile with three lines: FROM node:24-alpine, COPY hello.js /hello.js, CMD node /hello.js. Docker transcript: $ cat Dockerfile FROM node:24-alpine COPY hello.js /hello.js CMD ["node", "/hello.js"]

Your laptop~/hello

  • No open hatches

Lunchboxes (containers)

  • No containers yet

Frozen packs (images)

  • node:24-alpine4 layers · 244MB

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

A Dockerfile: The recipe: step-by-step lines that make an image. is a recipe for an image. FROM picks a frozen base pack. COPY adds your food. CMD says what to do when the box opens.

Try it

Put the recipe in order. The top line runs first.

First line at the top. Put these in order. Use the arrows, or drag.

  • COPY hello.js /hello.js
  • FROM node:24-alpine
  • CMD ["node", "/hello.js"]

Watch

docker build bakes two steps: FROM node:24-alpine, then COPY hello.js. docker images now lists hello:1.0. Docker transcript: $ docker build -t hello:1.0 . [+] Building 0.1s (7/7) FINISHED docker:default => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 107B 0.0s => [internal] load metadata for docker.io/library/node:24-alpine 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [1/2] FROM docker.io/library/node:24-alpine@sha256:8a32c8cf649a49915a6 0.0s => => resolve docker.io/library/node:24-alpine@sha256:8a32c8cf649a49915a6 0.0s => [internal] load build context 0.0s => => transferring context: 141B 0.0s => [2/2] COPY hello.js /hello.js 0.0s => exporting to image 0.1s => => exporting layers 0.0s => => exporting manifest sha256:44e03045f4c8b90ad6efee4446fa5b308798c4009 0.0s => => exporting config sha256:9c60021cdc96a7a0c482f11cac463756a3dab506a44 0.0s => => exporting attestation manifest sha256:069105ba22e077bc68b712e352a68 0.0s => => exporting manifest list sha256:7063ee281c8ba71514cc623bfa4a8d36ca2d 0.0s => => naming to docker.io/library/hello:1.0 0.0s => => unpacking to docker.io/library/hello:1.0 0.0s $ docker images hello i Info → U In Use IMAGE ID DISK USAGE CONTENT SIZE EXTRA hello:1.0 7063ee281c8b 244MB 62.5MB

Your laptop~/hello

  • No open hatches

Lunchboxes (containers)

  • No containers yet

Frozen packs (images)

  • node:24-alpine4 layers · 244MB

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

docker build -t hello:1.0 . bakes the recipe into an image. -t gives it a name and a tag. The dot means “use this folder”.

Try it

Your turn. Build the image, then run it once.

Your laptop~/hello

  • No open hatches

Lunchboxes (containers)

  • No containers yet

Frozen packs (images)

  • node:24-alpine4 layers · 244MB

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

Predict

You change the message in hello.js. Then you run hello:1.0 again. What prints?

Pick one answer.

Check

After hello.js changes, hello:1.0 still prints Hello from Kedai Kancil. A new build, hello:1.1, prints Hai lagi. Docker transcript: $ docker build -t hello:1.0 . [+] Building 0.1s (7/7) FINISHED docker:default => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 107B 0.0s => [internal] load metadata for docker.io/library/node:24-alpine 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [1/2] FROM docker.io/library/node:24-alpine@sha256:8a32c8cf649a49915a6 0.0s => => resolve docker.io/library/node:24-alpine@sha256:8a32c8cf649a49915a6 0.0s => [internal] load build context 0.0s => => transferring context: 141B 0.0s => [2/2] COPY hello.js /hello.js 0.0s => exporting to image 0.1s => => exporting layers 0.0s => => exporting manifest sha256:44e03045f4c8b90ad6efee4446fa5b308798c4009 0.0s => => exporting config sha256:9c60021cdc96a7a0c482f11cac463756a3dab506a44 0.0s => => exporting attestation manifest sha256:069105ba22e077bc68b712e352a68 0.0s => => exporting manifest list sha256:7063ee281c8ba71514cc623bfa4a8d36ca2d 0.0s => => naming to docker.io/library/hello:1.0 0.0s => => unpacking to docker.io/library/hello:1.0 0.0s $ echo "console.log('Hai lagi!');" > hello.js $ docker run --rm hello:1.0 Hello from Kedai Kancil! $ docker build -t hello:1.1 . [+] Building 0.1s (7/7) FINISHED docker:default => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 107B 0.0s => [internal] load metadata for docker.io/library/node:24-alpine 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [1/2] FROM docker.io/library/node:24-alpine@sha256:8a32c8cf649a49915a6 0.0s => => resolve docker.io/library/node:24-alpine@sha256:8a32c8cf649a49915a6 0.0s => [internal] load build context 0.0s => => transferring context: 126B 0.0s => [2/2] COPY hello.js /hello.js 0.0s => exporting to image 0.1s => => exporting layers 0.0s => => exporting manifest sha256:c6ef1a96f61d1ec6804b4ba4bfeb1e1ed2accc40f 0.0s => => exporting config sha256:d242cdff7c93b75afc3520cbd6f47f57a0df440c8d9 0.0s => => exporting attestation manifest sha256:b6268118f4da4929ec6a35bb5cf10 0.0s => => exporting manifest list sha256:b602534f7b4cc1dc5d80849b1a58d9348608 0.0s => => naming to docker.io/library/hello:1.1 0.0s => => unpacking to docker.io/library/hello:1.1 0.0s $ docker run --rm hello:1.1 Hai lagi!

Your laptop~/hello

  • No open hatches

Lunchboxes (containers)

  • No containers yet

Frozen packs (images)

  • node:24-alpine4 layers · 244MB

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

The old pack still says hello. A new build packs the new file. Change the recipe or the food? Build again.

You did it!

You can now write a recipe and bake it into an image.

Go deeper (optional)

A website on the nginx base needs no CMD. The base pack already has one. docker build reads the file called Dockerfile in the folder you name.

Real rep (optional), on your own computer:

Real mission

  1. mkdir hello && cd hello
  2. docker build -t hello:1.0 .
  3. docker run --rm hello:1.0

0 of 4 steps done · Your ticks are saved.