Docker Compose — Development — Practice Exercises

1 minute read

Practice setting up development workflows with Docker Compose.


Exercise 1: Bind Mount Hot Reload

Set up a Node.js service with bind mounts and nodemon for hot reload.

Solution
services:
  api:
    build: ./api
    volumes:
      - ./api:/app
      - /app/node_modules
    command: npx nodemon server.js
    ports:
      - "3000:3000"

Edit ./api/server.js and watch it auto-restart.


Exercise 2: Override File

Create a base compose.yml and a compose.override.yml that adds bind mounts and a debug port.

Solution

compose.yml:

services:
  api:
    image: node:20-alpine
    ports:
      - "3000:3000"

compose.override.yml:

services:
  api:
    build: ./api
    volumes:
      - ./api:/app
    ports:
      - "9229:9229"
    command: node --inspect=0.0.0.0:9229 server.js
docker compose config    # See merged result

Exercise 3: Multi-File Environments

Set up separate dev and prod compose files and switch between them.

Solution
# Development
docker compose -f compose.yml -f compose.dev.yml up -d

# Production
docker compose -f compose.yml -f compose.prod.yml up -d

Exercise 4: Compose Watch

Configure Compose watch to sync source files and rebuild on package.json changes.

Solution
services:
  api:
    build: ./api
    develop:
      watch:
        - action: sync
          path: ./api/src
          target: /app/src
        - action: rebuild
          path: ./api/package.json
docker compose watch

Exercise 5: Debug Setup

Configure a Python service for remote debugging with VS Code.

Solution
services:
  api:
    build: ./api
    volumes:
      - ./api:/app
    command: python -m debugpy --listen 0.0.0.0:5678 --wait-for-client app.py
    ports:
      - "5000:5000"
      - "5678:5678"

Add to .vscode/launch.json:

{
  "type": "python",
  "request": "attach",
  "name": "Attach to Docker",
  "connect": { "host": "localhost", "port": 5678 },
  "pathMappings": [{
    "localRoot": "${workspaceFolder}/api",
    "remoteRoot": "/app"
  }]
}