Docker Environment Variables and .env Files

In the world of containerization, flexibility is key. You don't want to bake sensitive information like database passwords or API keys directly into your Docker images. This is where Environment Variables and .env files come into play. They allow you to configure your applications dynamically, making your images portable across development, testing, and production environments.

What are Environment Variables?

Environment variables are dynamic-named values that can affect the way running processes behave on a computer. In Docker, they are used to pass configuration settings into a container at runtime. This ensures that the same image can behave differently based on the environment it is running in.

Methods to Pass Environment Variables

There are several ways to provide environment variables to your Docker containers. Understanding the priority of these methods is crucial for effective configuration management.

  • The -e Flag: Used with the docker run command for quick, one-off variables.
  • Dockerfile ENV Instruction: Used to set default values within the image itself.
  • Docker Compose: Defining variables in a docker-compose.yml file.
  • .env Files: A dedicated text file used to store multiple variables in key-value pairs.

1. Using the -e Flag

The simplest way to pass a variable is during the container startup. This overrides any default values set in the Dockerfile.

docker run -e APP_COLOR=blue -e VERSION=1.0 my-web-app

2. Using the ENV Instruction in Dockerfile

You can define default environment variables inside your Dockerfile. These are baked into the image but can be overridden later.

FROM node:14
ENV PORT=3000
ENV APP_ENV=production
COPY . .
CMD ["npm", "start"]
    

The Power of .env Files

Managing dozens of variables via the command line is error-prone and messy. A .env file is a simple text file that stores configuration in a KEY=VALUE format. Docker Compose automatically looks for a file named .env in the project directory.

Example of a .env file:

DB_HOST=localhost
DB_USER=admin
DB_PASS=s3cureP@ssword
API_KEY=xyz123456
    

Using .env with Docker Compose

In your docker-compose.yml, you can reference these variables using the ${VARIABLE_NAME} syntax.

services:
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: ${DB_PASS}
      POSTGRES_USER: ${DB_USER}
    

Variable Precedence Flowchart

When multiple sources define the same variable, Docker follows a specific order of priority. Here is a simplified flow of how Docker resolves these values:

[Highest Priority]
      |
      |-- 1. Values set via 'docker run -e' or CLI overrides
      |-- 2. Values set in the 'environment' section of docker-compose.yml
      |-- 3. Values defined in the '.env' file
      |-- 4. Values defined in the Dockerfile 'ENV' instruction
      |
[Lowest Priority]
    

Real-World Use Cases

  • Database Connectivity: Passing different database URLs for local development (localhost) versus production (cloud-db-instance).
  • Feature Toggles: Enabling or disabling specific application features (e.g., ENABLE_BETA_UI=true) without changing code.
  • Security: Keeping sensitive credentials out of version control by adding the .env file to .gitignore.
  • Microservices: Configuring service discovery addresses for different microservices to communicate.

Common Mistakes to Avoid

  • Committing .env to Git: Never push your .env files containing secrets to public or private repositories. Always use a .env.example template instead.
  • Incorrect Syntax: Ensure there are no spaces around the equals sign in your .env file (e.g., use KEY=VALUE, not KEY = VALUE).
  • Over-reliance on Dockerfile ENV: Avoid putting sensitive data in the Dockerfile ENV instruction, as anyone with access to the image can see those values using docker inspect.
  • Missing File: Forgetting to provide the .env file in a new environment, leading to "variable not set" warnings or application crashes.

Interview Notes: Docker Environment Variables

  • Question: How do you view environment variables inside a running container?
  • Answer: You can use the command docker exec [container_id] env to list all active variables.
  • Question: What is the difference between ARG and ENV?
  • Answer: ARG is used only during the image build process and is not available in the running container. ENV is available during the build and persists when the container is running.
  • Question: How does Docker Compose handle a missing .env file?
  • Answer: It will usually print a warning and treat the variables as empty strings unless default values are provided in the YAML file.

Summary

Managing configuration through Environment Variables and .env files is a fundamental skill in modern DevOps. It promotes the "Build Once, Run Anywhere" philosophy by separating the application code from its configuration. By using .env files with Docker Compose, you create a clean, maintainable, and secure way to manage your microservices across various stages of the software development lifecycle. Remember to protect your secrets and understand the order of precedence to avoid configuration conflicts.

In our next lesson, we will explore Docker Networking Basics to understand how these configured containers communicate with each other.