🐳 Docker Learning Hub
Lesson 7 • Environment variables and configuration
Lesson 7

Environment variables and app configuration

This page explains how Docker containers receive configurable values like app port, database host, and runtime mode without changing the source code itself.

Main idea

Environment variables are values passed into an app from outside the code.

Main use

They help you change configuration for development, testing, and production without rewriting the application.

Main warning

Secrets like passwords and API keys should be handled carefully, even when using environment variables.

Hardcoded config

Value written inside code
Harder to change across environments
Less flexible for teams

Environment-based config

Value comes from outside code
Easy to change per environment
Cleaner deployment workflow

Common examples

PORT=3000 DB_HOST=db DB_USER=root DB_PASSWORD=secret123 NODE_ENV=development

Why this matters

The same app can use different ports, databases, or runtime modes depending on where it runs, without changing the source code.

Using `docker run`

docker run -d -p 3000:3000 \ -e PORT=3000 \ -e NODE_ENV=development \ my-app

Using Compose

services: app: build: . environment: PORT: 3000 DB_HOST: db NODE_ENV: development

Full Compose example with environment variables

services: app: build: . ports: - "3000:3000" environment: PORT: 3000 DB_HOST: db NODE_ENV: development depends_on: - db db: image: mysql:8 environment: MYSQL_ROOT_PASSWORD: rootpass
In this setup, the app gets its port, database host, and mode from environment variables rather than from hardcoded values.

What about `.env` files?

PORT=3000 DB_HOST=db DB_USER=root DB_PASSWORD=secret123 NODE_ENV=development

A `.env` file can keep configuration values in one place, which makes Compose files cleaner and easier to maintain.

Common beginner mistakes

  • Hardcoding values directly into code
  • Using the wrong variable name
  • Putting secrets in public places carelessly
  • Using `localhost` for another container instead of the service name

How Compose uses `.env`

services: app: build: . ports: - "${PORT}:3000" environment: PORT: ${PORT} DB_HOST: ${DB_HOST} NODE_ENV: ${NODE_ENV}

Here, Compose reads values from the `.env` file and replaces placeholders like ${PORT} before starting the service.

How app code reads variables

const port = process.env.PORT || 3000; const dbHost = process.env.DB_HOST;

This is how a Node.js app reads configuration that Docker passes into the container at runtime.

`.env` workflow summary

Step 1
Store values like PORT=3000 and DB_HOST=db inside a `.env` file.
Step 2
Reference them inside Compose using syntax like ${PORT}.
Step 3
Let the app read them through code like process.env.PORT.
Step 4
Keep real secrets out of public repositories and handle them carefully.

What you learned in Lesson 7

Environment variables separate code from configuration
The app code can stay the same while values change per environment.
Docker can inject values at runtime
Both `docker run` and Compose support environment-based configuration.
Compose becomes more useful with config
You can combine services, volumes, networks, and environment settings together.
Secrets still need care
Environment variables help, but sensitive values should still be handled responsibly.

Next page: Lesson 8 combines Dockerfile, Compose, volumes, networks, and configuration in one small real Docker project.