By using this site, you agree to the Privacy Policy and Terms of Use.
Accept
World of SoftwareWorld of SoftwareWorld of Software
  • News
  • Software
  • Mobile
  • Computing
  • Gaming
  • Videos
  • More
    • Gadget
    • Web Stories
    • Trending
    • Press Release
Search
  • Privacy
  • Terms
  • Advertise
  • Contact
Copyright © All Rights Reserved. World of Software.
Reading: Docker Environment Variables: Development vs Production Made Simple | HackerNoon
Share
Sign In
Notification Show More
Font ResizerAa
World of SoftwareWorld of Software
Font ResizerAa
  • Software
  • Mobile
  • Computing
  • Gadget
  • Gaming
  • Videos
Search
  • News
  • Software
  • Mobile
  • Computing
  • Gaming
  • Videos
  • More
    • Gadget
    • Web Stories
    • Trending
    • Press Release
Have an existing account? Sign In
Follow US
  • Privacy
  • Terms
  • Advertise
  • Contact
Copyright © All Rights Reserved. World of Software.
World of Software > Computing > Docker Environment Variables: Development vs Production Made Simple | HackerNoon
Computing

Docker Environment Variables: Development vs Production Made Simple | HackerNoon

News Room
Last updated: 2025/10/17 at 12:21 PM
News Room Published 17 October 2025
Share
Docker Environment Variables: Development vs Production Made Simple | HackerNoon
SHARE

When building applications with Docker, managing environment variables across different environments can be tricky. Here’s a clean, practical approach we’ll demonstrate with a real FastAPI application that keeps development smooth while ensuring production deployments are secure.

The Problem We’re Solving

Most developers start with a simple setup that works locally but creates problems in production:

# This works locally but causes issues in production

version: '3.8' 
services: 
  my-app: 
    build: . 
    env_file: .env  # This will override production env vars!

Problems:

  • .env file overrides production environment variables
  • Sensitive data accidentally gets deployed
  • Production servers can’t inject their own configuration

Our Solution: Clean Separation with Docker Compose

We’ll build a FastAPI application that demonstrates the right way to handle this.

The Application Structure

fastapi-docker-env-demo/

├── main.py # FastAPI application
├── requirements.txt # Dependencies
├── Dockerfile # Production-ready container
├── docker-compose.yml # Base config (production-ready)
├── docker-compose.override.yml # Development overrides
├── .env # Local development variables
└── .env.production.example # Production reference

Step 1: FastAPI Application with Environment Config

main.py:

import os
from fastapi import FastAPI
import uvicorn
from dotenv import load_dotenv

# Load environment variables from .env file if it exists
load_dotenv()

app = FastAPI(
    title="Docker Environment Demo",
    description="Demonstrating Docker environment variable best practices",
    version="1.0.0"
)

# Environment configuration with sensible defaults
class Config:
    # Application settings
    APP_NAME = os.getenv("APP_NAME", "Docker Environment Demo")
    ENVIRONMENT = os.getenv("ENVIRONMENT", "development")
    DEBUG = os.getenv("DEBUG", "false").lower() == "true"
    HOST = os.getenv("HOST", "0.0.0.0")
    PORT = int(os.getenv("PORT", "8000"))

    # Database settings
    DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./dev.db")

    # API settings
    API_KEY = os.getenv("API_KEY", "dev-api-key-12345")
    SECRET_KEY = os.getenv("SECRET_KEY", "dev-secret-key")

    # Third-party services
    REDIS_URL = os.getenv("REDIS_URL", "redis://localhost:6379")
    EMAIL_SERVICE_URL = os.getenv("EMAIL_SERVICE_URL", "https://api.dev-email-service.com")

    # Feature flags
    ENABLE_CACHING = os.getenv("ENABLE_CACHING", "true").lower() == "true"
    ENABLE_ANALYTICS = os.getenv("ENABLE_ANALYTICS", "false").lower() == "true"

config = Config()

@app.get("/")
async def root():
    """Welcome endpoint with basic app info"""
    return {
        "message": f"Welcome to {config.APP_NAME}!",
        "environment": config.ENVIRONMENT,
        "debug": config.DEBUG,
        "version": "1.0.0"
    }



@app.get("/env")
async def get_environment_variables():
    """Shows all environment variables currently loaded by the app"""
    return {
        "APP_NAME": config.APP_NAME,
        "ENVIRONMENT": config.ENVIRONMENT,
        "DEBUG": config.DEBUG,
        "HOST": config.HOST,
        "PORT": config.PORT,
        "DATABASE_URL": config.DATABASE_URL,
        "API_KEY": config.API_KEY,
        "SECRET_KEY": config.SECRET_KEY,
        "REDIS_URL": config.REDIS_URL,
        "EMAIL_SERVICE_URL": config.EMAIL_SERVICE_URL,
        "ENABLE_CACHING": config.ENABLE_CACHING,
        "ENABLE_ANALYTICS": config.ENABLE_ANALYTICS
    }

if __name__ == "__main__":
    uvicorn.run(
        "main:app",
        host=config.HOST,
        port=config.PORT,
        reload=config.DEBUG,
        log_level="debug" if config.DEBUG else "info"
    )

Step 2: Production-Ready Docker Configuration

Dockerfile:

FROM python:3.11-slim

WORKDIR /app

# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application
COPY . .

# Security: non-root user
RUN adduser --disabled-password appuser && chown -R appuser /app
USER appuser

EXPOSE 8000

CMD ["python", "main.py"]

docker-compose.yml (Production-ready base):

version: '3.8'
services:
  fastapi-app:
    build: .
    image: fastapi-env-demo:latest
    container_name: fastapi-env-demo
    ports:
      - "8000:8000"
    environment:
      - PYTHONPATH=/app
    restart: unless-stopped

Step 3: Development Override Configuration

docker-compose.override.yml (Development additions):

version: '3.8'

services:
  fastapi-app:
    env_file:
      - .env
    environment:
      # Override for development
      - ENVIRONMENT=development
      - DEBUG=true
    volumes:
      # Enable hot reload in development
      - .:/app
    command: ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

Step 4: Environment Variable Files

.env (Local development):

# Development environment variables
APP_NAME=Docker Environment Demo
ENVIRONMENT=development
DEBUG=true
HOST=0.0.0.0
PORT=8000

# Database settings
DATABASE_URL=sqlite:///./dev.db

# API settings
API_KEY=dev-api-key-12345
SECRET_KEY=dev-secret-key-for-local-development

# Third-party services
REDIS_URL=redis://localhost:6379
EMAIL_SERVICE_URL=https://api.dev-email-service.com

# Feature flags
ENABLE_CACHING=true
ENABLE_ANALYTICS=false

.env.production.example (Production reference):

# Set these on your production server
APP_NAME=My Production API
ENVIRONMENT=production
DEBUG=false
DATABASE_URL=postgresql://user:pass@db:5432/prod
API_KEY=your-production-api-key
SECRET_KEY=your-super-secure-production-secret
REDIS_URL=redis://redis:6379
EMAIL_SERVICE_URL=https://api.your-email-service.com
ENABLE_CACHING=true
ENABLE_ANALYTICS=true

How It Works

Local Development Workflow

# Simply run this - Docker Compose automatically merges the files 
docker-compose up --build

What happens:

  1. Loads base docker-compose.yml
  2. Automatically merges docker-compose.override.yml
  3. Loads your .env file via env_file directive
  4. Enables hot reload and debug mode
  5. Mounts source code for live editing

Production Deployment

# Deploy using only the base configuration docker-compose -f 
docker-compose.yml up -d --build

then using .env.production.example file in the production environment.For example we are deploying to Digitalocean app platform that is using docker registry. you should connect to the docker registry, tag you images like the following then push.

docker tag <image-name>:<tag> <registry-url>/<reg-name>/<image-name>:<tag> docker push <registry-url>/<reg-name>/<image-name>:<tag>

in Digitalocean app platform, you can bluk load the env variables by going to settings, then in the “App-LevelEnvironment Variables” section choose “Bulk Editor” like here:

and here you go, let test now

Testing Your Setup

The /env endpoint makes it super easy to verify your configuration:

Development Test

curl http://localhost:8000/env

Response:

Production Test

curl http://your-server:8000/env

For example you deploy to Digitalocean app platform that is

Response:

Quick Start

  1. Clone the project
  2. Start development: docker-compose up --build
  3. Visit: http://localhost:8000/env to see your configuration

Conclusion

This approach gives you the best of both worlds:

  • Easy local development with automatic .env loading
  • Clean production deployments that respect server environment variables
  • Same Docker image works in all environments
  • Simple testing with the /env endpoint

The key insight: Keep your base docker-compose.yml production-ready, and use override files for development conveniences.

This pattern scales from simple applications to complex microservices and works with any deployment platform. Your development team gets a smooth workflow, and your production deployments stay secure and maintainable.

The complete working example is available as a FastAPI application that demonstrates all these concepts in action.

Sign Up For Daily Newsletter

Be keep up! Get the latest breaking news delivered straight to your inbox.
By signing up, you agree to our Terms of Use and acknowledge the data practices in our Privacy Policy. You may unsubscribe at any time.
Share This Article
Facebook Twitter Email Print
Share
What do you think?
Love0
Sad0
Happy0
Sleepy0
Angry0
Dead0
Wink0
Previous Article Apple’s new five-year deal with Formula 1: What it means for US fans
Next Article Save over 0 on the Sony WH-1000XM5 headphones at Walmart Save over $100 on the Sony WH-1000XM5 headphones at Walmart
Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Stay Connected

248.1k Like
69.1k Follow
134k Pin
54.3k Follow

Latest News

Varda says it has proven space manufacturing works — now it wants to make it boring |  News
Varda says it has proven space manufacturing works — now it wants to make it boring | News
News
Xiaomi rolls out HyperOS 3 with “super island” interface, similar to Apple’s dynamic island · TechNode
Xiaomi rolls out HyperOS 3 with “super island” interface, similar to Apple’s dynamic island · TechNode
Computing
Best Air Fryer Toaster Oven of 2025
Best Air Fryer Toaster Oven of 2025
News
Shanghai Jiao Tong University launches China’s first undergraduate major in embodied AI · TechNode
Shanghai Jiao Tong University launches China’s first undergraduate major in embodied AI · TechNode
Computing

You Might also Like

Xiaomi rolls out HyperOS 3 with “super island” interface, similar to Apple’s dynamic island · TechNode
Computing

Xiaomi rolls out HyperOS 3 with “super island” interface, similar to Apple’s dynamic island · TechNode

1 Min Read
Shanghai Jiao Tong University launches China’s first undergraduate major in embodied AI · TechNode
Computing

Shanghai Jiao Tong University launches China’s first undergraduate major in embodied AI · TechNode

1 Min Read
Chinese firms rush to get in on the robotaxi craze with AI models · TechNode
Computing

Chinese firms rush to get in on the robotaxi craze with AI models · TechNode

4 Min Read
TSMC 2nm leak case solved, three suspects plead guilty with maximum sentences of 14 years · TechNode
Computing

TSMC 2nm leak case solved, three suspects plead guilty with maximum sentences of 14 years · TechNode

1 Min Read
//

World of Software is your one-stop website for the latest tech news and updates, follow us now to get the news that matters to you.

Quick Link

  • Privacy Policy
  • Terms of use
  • Advertise
  • Contact

Topics

  • Computing
  • Software
  • Press Release
  • Trending

Sign Up for Our Newsletter

Subscribe to our newsletter to get our newest articles instantly!

World of SoftwareWorld of Software
Follow US
Copyright © All Rights Reserved. World of Software.
Welcome Back!

Sign in to your account

Lost your password?