Environment Variables - potatoscript/django GitHub Wiki

🔒 Environment Variables & Secrets in Django

In modern web development, it's crucial to keep sensitive information such as API keys, database credentials, and other secrets secure. Django makes it easy to manage these sensitive pieces of information using environment variables. By separating your sensitive data from your codebase, you reduce the risk of exposing it to unauthorized access.

In this tutorial, we'll learn how to:

  • Use environment variables to store sensitive data.
  • Set up Django to securely access these environment variables.
  • Manage secrets in a way that keeps them safe and out of your codebase.

🧩 Step 1: Understanding Environment Variables

Environment variables are key-value pairs stored outside of your codebase. They can store sensitive information like:

  • API Keys
  • Database Credentials
  • Email Server Information
  • Secret Keys

Instead of hardcoding these values into your code (which is not secure), you reference them as environment variables. This keeps your sensitive data protected and ensures your code can run on different environments (development, staging, production) without needing to change the code.


🧩 Step 2: Setting Up Environment Variables

🛠️ Step 2.1: Install python-dotenv

To easily load environment variables from a .env file into your Django project, you can use the python-dotenv package. This package allows you to store environment variables in a .env file and load them into your application.

  1. Install python-dotenv:

    pip install python-dotenv
    
  2. Create a .env file at the root of your project (next to manage.py):

    SECRET_KEY=your-secret-key-here
    DATABASE_URL=postgres://user:password@localhost:5432/dbname
    DEBUG=True
    

    Here, we have three environment variables:

    • SECRET_KEY: Django’s secret key for cryptographic operations.
    • DATABASE_URL: The connection string for your database.
    • DEBUG: Whether Django should run in debug mode or not.

🧩 Step 3: Loading Environment Variables in Django

🛠️ Step 3.1: Modify settings.py to Use Environment Variables

  1. Import and load environment variables in settings.py:

    At the top of your settings.py, add:

    import os
    from dotenv import load_dotenv
    
    load_dotenv()  # This loads environment variables from the .env file
    
  2. Use environment variables in settings.py:

    Instead of hardcoding sensitive values in settings.py, replace them with references to the environment variables:

    # settings.py
    SECRET_KEY = os.getenv('SECRET_KEY', 'fallback-secret-key')  # A fallback key if not found
    DEBUG = os.getenv('DEBUG', 'True') == 'True'  # Convert DEBUG to a boolean
    
    # Database setup using DATABASE_URL from the environment
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': os.getenv('DB_NAME'),
            'USER': os.getenv('DB_USER'),
            'PASSWORD': os.getenv('DB_PASSWORD'),
            'HOST': os.getenv('DB_HOST', 'localhost'),
            'PORT': os.getenv('DB_PORT', '5432'),
        }
    }
    

🛠️ Step 3.2: Working with Different Environments

By using environment variables, you can set different values for DEBUG, SECRET_KEY, and other variables based on the environment you're working in. For example, in production, you could set DEBUG=False and use a real database URL.

  • Development: Keep DEBUG=True and use a local database.
  • Production: Set DEBUG=False and use a secure database.

You can keep your .env file in the development environment, but in production, use actual environment variables set directly in the operating system or through a deployment platform like Heroku, AWS, or Docker.


🧩 Step 4: Securely Managing Secrets

When working with secrets (such as API keys or database credentials), it’s crucial to store them securely. Here are some tips to help you manage secrets:

🛡️ Step 4.1: Avoid Committing .env to Version Control

Never commit your .env file to version control (e.g., Git). To ensure this, add the .env file to your .gitignore:

# .gitignore
.env

This prevents your secrets from being accidentally shared with others.

🛡️ Step 4.2: Use Secrets Management Services

In production environments, you should use a dedicated secrets management service. Many cloud platforms provide ways to securely store and access secrets:

  • AWS Secrets Manager
  • Google Cloud Secret Manager
  • Heroku Config Vars

These services can automatically inject secrets into your application, keeping them secure and easily accessible.


🧩 Step 5: Example: Using Environment Variables for Email Settings

Django allows you to send emails from your application. You can store the email credentials securely using environment variables.

🛠️ Step 5.1: Add Email Settings to .env

In your .env file, store your email credentials:

EMAIL_HOST=smtp.mailtrap.io
EMAIL_PORT=587
EMAIL_HOST_USER=your-email-user
EMAIL_HOST_PASSWORD=your-email-password
[email protected]

🛠️ Step 5.2: Update settings.py to Use Environment Variables

In settings.py, use the environment variables for your email settings:

# settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = os.getenv('EMAIL_HOST')
EMAIL_PORT = os.getenv('EMAIL_PORT', 587)  # Default port is 587
EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD')
DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL')

🛠️ Step 5.3: Sending an Email

Now that your email settings are set up, you can send emails using Django’s send_mail function:

from django.core.mail import send_mail

send_mail(
    'Test Email',
    'This is a test email sent from Django.',
    '[email protected]',
    ['[email protected]'],
    fail_silently=False,
)

🧩 Step 6: Example: Using Environment Variables in a Custom API

If you’re integrating with an external API (like a payment gateway), you would store your API key in the .env file and reference it in settings.py.

🛠️ Step 6.1: Add API Key to .env

PAYMENT_API_KEY=your-payment-api-key

🛠️ Step 6.2: Access API Key in Your Application

In your Django views or other files, you can access the API key like this:

import os

API_KEY = os.getenv('PAYMENT_API_KEY')

This keeps your sensitive API keys secure and prevents them from being exposed in your source code.


🧩 Step 7: Using Environment Variables with Docker

If you’re deploying your Django application using Docker, you can set environment variables in your Dockerfile or Docker Compose configuration.

🛠️ Step 7.1: Docker Compose Example

In docker-compose.yml, you can pass environment variables to the containers:

version: '3'

services:
  web:
    build: .
    environment:
      - SECRET_KEY=your-secret-key-here
      - DEBUG=False
      - DATABASE_URL=postgres://user:password@localhost:5432/dbname
    ports:
      - "8000:8000"

🛠️ Step 7.2: Dockerfile Example

Alternatively, you can set environment variables in the Dockerfile:

ENV SECRET_KEY=your-secret-key-here
ENV DEBUG=False

By using Docker in this way, you can securely pass environment variables to your Django application at runtime.


📝 Summary

Step What Happens
1. Install python-dotenv Install python-dotenv to load environment variables from a .env file.
2. Set Environment Variables Define sensitive data like API keys and database credentials in the .env file.
3. Load Variables in Django Modify settings.py to load and use environment variables securely.
4. Secure Secrets Management Avoid committing .env to version control, and use secrets management services.
5. Use Variables for Email/API Configure email or external API services with environment variables for security.
6. Use with Docker Pass environment variables to your Django app through Docker.