Docker Compose — Build — Practice Exercises

1 minute read

Test your understanding of building images with Docker Compose.


Exercise 1: Basic Build

Create a simple Node.js Dockerfile and build it using Compose.

Solution

api/Dockerfile:

FROM node:20-alpine
WORKDIR /app
COPY package.json .
RUN echo '{"name":"api","scripts":{"start":"node server.js"}}' > package.json
RUN echo 'require("http").createServer((req,res)=>{res.end("OK")}).listen(3000)' > server.js
CMD ["node", "server.js"]

compose.yml:

services:
  api:
    build: ./api
    ports:
      - "3000:3000"
docker compose build
docker compose up -d
curl http://localhost:3000    # OK

Exercise 2: Build Args

Pass a NODE_VERSION build arg to select the base image version.

Solution

Dockerfile:

ARG NODE_VERSION=20
FROM node:${NODE_VERSION}-alpine
WORKDIR /app
CMD ["node", "--version"]
services:
  api:
    build:
      context: .
      args:
        NODE_VERSION: "18"
docker compose build
docker compose run --rm api   # Should show v18.x.x

Exercise 3: Multi-Stage Target

Create a multi-stage Dockerfile with development and production stages. Use target: to select one.

Solution
FROM alpine AS development
RUN echo "dev mode"
CMD ["echo", "development"]

FROM alpine AS production
RUN echo "prod mode"
CMD ["echo", "production"]
services:
  app:
    build:
      context: .
      target: production
docker compose build
docker compose run --rm app    # production

Exercise 4: Tag and Push

Build an image, tag it with a version, and list the result.

Solution
services:
  api:
    build: ./api
    image: myregistry/api:v1.0.0
docker compose build
docker compose images     # Shows myregistry/api:v1.0.0

Exercise 5: Dynamic Version Tag

Use .env to set the version tag dynamically.

Solution

.env:

VERSION=2.1.0
services:
  api:
    build: ./api
    image: myregistry/api:${VERSION}
docker compose build
docker compose images     # Shows myregistry/api:2.1.0