Skip to main content
Docker Basics Tutorial
CHAPTER 12 Beginner

Docker Environment Variables and Secrets

Updated: May 15, 2026
20 min read

# CHAPTER 12

Docker Environment Variables and Secrets

1. Introduction

If you write a Python application that connects to an AWS S3 bucket, it requires an API Key. If you hardcode that API key directly into your app.py code and push it to GitHub, hackers will scrape it and compromise your AWS account. Modern application architecture demands that sensitive configuration data be strictly decoupled from the application code. In this chapter, we will master the secure injection of configuration via Environment Variables and .env files, ensuring our Dockerized applications are flexible, portable, and secure.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Understand the 12-Factor App methodology regarding configuration.
  • Inject Environment Variables via the Docker CLI (-e flag).
  • Centralize variables using an .env file with Docker Compose.
  • Prevent hardcoded secrets from entering Version Control.
  • Understand the conceptual basics of Docker Secrets in Swarm/Kubernetes.

3. Beginner-Friendly Explanation

Imagine you are building a spy car (Your Application).
  • Hardcoding (Dangerous): You engrave the missile launch codes directly onto the dashboard. If the enemy steals the car, they instantly have the launch codes.
  • Environment Variables (Secure): The dashboard has a blank slot. When the spy (The Environment) gets into the car, they insert a temporary smart-key containing the codes into the slot. When the spy leaves the car, they take the key with them. The car remains functional, but the secrets are never permanently attached to it.

4. The ENV Instruction in Dockerfiles

You can set default environment variables directly inside the blueprint using the ENV instruction in your Dockerfile.
dockerfile
12345
FROM node:18-alpine
ENV PORT=3000
ENV NODE_ENV=production
COPY . /app
CMD ["npm", "start"]

These are excellent for defining *non-sensitive* default application settings, ensuring the container knows it should run in "production" mode on port 3000 by default.

5. Overriding via the CLI (-e)

You can override any internal container variable, or inject brand new ones, at runtime using the -e flag in the terminal.
bash
1
docker run -e PORT=8080 -e API_KEY=xyz123 my-node-app

*Problem:* Typing secrets directly into the terminal is bad practice. Terminal histories (like ~/.bash_history) record every command you type, meaning your API key is now saved in plain text on your hard drive!

6. The .env File and Docker Compose

The industry standard solution for local development is the .env file.
  1. 1. You create a simple text file named .env in the same directory as your docker-compose.yml.
  1. 2. Inside .env, you define your secrets:
text
12
DATABASE_PASSWORD=supersecret99
STRIPE_API_KEY=sk_live_12345
  1. 3. In your docker-compose.yml, you reference these variables using ${VARIABLE_NAME} syntax:
yaml
123456789
services:
  db:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=${DATABASE_PASSWORD}
  web:
    image: php:8.2-apache
    environment:
      - STRIPE_KEY=${STRIPE_API_KEY}

When you run docker-compose up, Compose silently reads the .env file, injects the secrets into the containers, and launches the application perfectly.

7. Mini Project: Secure Application Configuration

Let's build a secure configuration pipeline.

Step-by-Step Tutorial:

  1. 1. Create a folder named secure-app.
  1. 2. Crucial First Step: Create a .gitignore file and type .env inside it. *This ensures you never accidentally push your passwords to GitHub!*
  1. 3. Create the .env file:

text
1
APP_THEME=dark_mode
  1. 4. Create an index.php file that reads the variable:
php
1234
<?php
$theme = getenv(&#039;APP_THEME');
echo "<h1>The application is running in: $theme</h1>";
?>
  1. 5. Create docker-compose.yml:
yaml
12345678910
version: &#039;3.8'
services:
  web:
    image: php:8.2-apache
    ports:
      - "8000:80"
    volumes:
      - ./:/var/www/html
    environment:
      - APP_THEME=${APP_THEME}
  1. 6. Run docker-compose up -d. Check http://localhost:8000. It will display "dark_mode".
  1. 7. Edit the .env file to say APP_THEME=light_mode. Run docker-compose up -d again. Docker automatically detects the environment change and updates the running container securely!

8. Real-World Scenarios

A team has a Staging server and a Production server. They use the exact same Docker Image for both servers. How does the image know which database to connect to? The Staging server has a local .env file containing the Staging Database IP. The Production server has a local .env file containing the Production Database IP. The code never changes, only the environment changes. This is the core philosophy of modern DevOps.

9. Best Practices

  • Provide a .env.example file: Because you .gitignore the real .env file, new developers cloning your repository won't know what variables the app needs! Always commit a .env.example file containing dummy data (e.g., DB_PASSWORD=your_password_here). The developer copies the example file, renames it to .env, and fills in their real passwords.

10. Common Mistakes

  • Hardcoding Secrets in the Dockerfile: Never use the ENV or ARG instructions in a Dockerfile to bake passwords into the image. Anyone who pulls your image from Docker Hub can run docker inspect <image_name> and read your passwords in plain text! Passwords must only be injected at runtime.

11. Exercises

  1. 1. What is the fundamental security reason for adding the .env file to your project's .gitignore list?
  1. 2. Contrast the use-case for utilizing the ENV instruction within a Dockerfile versus injecting variables at runtime via a docker-compose.yml file.

12. FAQs

Q: What are Docker Secrets? A: .env files are great for local development, but in massive enterprise production clusters (like Docker Swarm), saving passwords in flat text files on servers is insecure. Docker Secrets is a feature where the password is encrypted at rest, transmitted securely over the network, and only decrypted directly into the RAM of the specific container that needs it.

13. Interview Questions

  • Q: Explain the 12-Factor App principle regarding "Config." Why is it an anti-pattern to store database credentials within application configuration files (e.g., a PHP config.php file) committed to version control?
  • Q: An auditor discovers that a developer has baked an AWS API key into a custom Docker image using the ENV instruction in the Dockerfile. Explain why this is a critical security breach and detail the architectural changes required to resolve it.

14. Summary

In Chapter 12, we decoupled our sensitive configuration from our static codebase. We adhered to industry-standard security principles by utilizing Environment Variables to dynamically dictate application behavior. We mastered the .env file paradigm, combining it with Docker Compose to inject critical secrets like API keys and database passwords safely at runtime, ensuring our source code repositories remain fundamentally clean and hacker-resistant.

15. Next Chapter Recommendation

Our application is running securely. But suddenly, the container crashes and shuts down. How do we figure out what went wrong? Proceed to Chapter 13: Docker Logs, Monitoring, and Debugging.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·