Docker Compose — Environment — Practice Exercises

1 minute read

Test your understanding of environment variables, env files, substitution, and secrets.


Exercise 1: Inline Environment Variables

Set NODE_ENV=production and PORT=3000 on a Node.js service using the environment: key. Verify with docker compose exec.

Solution
services:
  api:
    image: node:20-alpine
    command: sleep 3600
    environment:
      NODE_ENV: production
      PORT: "3000"
docker compose up -d
docker compose exec api printenv NODE_ENV
docker compose exec api printenv PORT

Output:

production
3000

Exercise 2: Load from env_file

Create a .env.app file with three variables and load it using env_file:.

Solution

.env.app:

APP_NAME=myapi
APP_PORT=8080
APP_ENV=staging
services:
  api:
    image: alpine
    command: sleep 3600
    env_file:
      - .env.app
docker compose up -d
docker compose exec api env | grep APP_

Output:

APP_NAME=myapi
APP_PORT=8080
APP_ENV=staging

Exercise 3: Variable Substitution with Defaults

Use .env to set a database tag, with a default fallback in compose.yml.

Solution

.env:

DB_TAG=16
services:
  db:
    image: postgres:${DB_TAG:-15}
docker compose config | grep image

Output: image: postgres:16

Remove DB_TAG from .env and re-run — it should fall back to 15.


Exercise 4: Required Variable

Use ${VAR:?message} to make a variable required. Verify Compose fails when it’s missing.

Solution
services:
  api:
    image: myapi:${API_TAG:?API_TAG is required}
# Without setting API_TAG:
docker compose config

Output:

Error: API_TAG is required

Exercise 5: Secrets

Create a secret from a file and use it in a Postgres container.

Solution
mkdir -p secrets
echo "supersecret" > secrets/db_password.txt
services:
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt
docker compose up -d
docker compose exec db cat /run/secrets/db_password

Output: supersecret