Docker secrets passing as environment variable

2 min read 06-10-2024
Docker secrets passing as environment variable


Unlocking Secrets: Passing Sensitive Data to Docker Containers with Environment Variables

Docker containers are a powerful tool for deploying applications, but how do you securely manage sensitive data like API keys, database credentials, and passwords? Sharing these secrets directly in the Dockerfile or within the container image itself is a major security risk.

Fortunately, Docker offers a solution through environment variables and secrets. This article will guide you on how to pass secrets to your Docker containers using environment variables, keeping your sensitive information secure.

Scenario:

Let's say you have a web application that connects to a database. You need to store the database connection credentials (username, password, host, etc.) securely and pass them to the container at runtime.

Original Code:

FROM nginx:latest

# **SECURITY RISK: Exposing database credentials directly**
ENV DB_USER="username" 
ENV DB_PASSWORD="password"
ENV DB_HOST="localhost"
ENV DB_PORT="5432"

COPY . /usr/share/nginx/html

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

This code snippet exposes the database credentials directly within the Dockerfile, making them vulnerable to potential security breaches.

Solution: Docker Secrets and Environment Variables

The recommended approach involves using Docker secrets and environment variables to securely manage sensitive data.

  1. Create a Docker secret:

    docker secret create db_credentials db_user:username db_password:password db_host:localhost db_port:5432
    

    This command creates a secret named db_credentials and stores the database credentials as key-value pairs.

  2. Use the secret in your Dockerfile:

    FROM nginx:latest
    
    # Use environment variable to access secret at runtime
    ENV DB_USER=${DB_USER}
    ENV DB_PASSWORD=${DB_PASSWORD}
    ENV DB_HOST=${DB_HOST}
    ENV DB_PORT=${DB_PORT}
    
    COPY . /usr/share/nginx/html
    
    EXPOSE 80
    CMD ["nginx", "-g", "daemon off;"]
    

    The ENV directives are now using the DB_USER, DB_PASSWORD, DB_HOST, and DB_PORT variables. These variables will be automatically populated at runtime with the values from the secret.

  3. Run the container with the secret:

    docker run -d --name my-web-app -e DB_USER -e DB_PASSWORD -e DB_HOST -e DB_PORT -v $(pwd):/usr/share/nginx/html --secret db_credentials my-web-app
    

    This command runs the container with the name my-web-app, mounts the current directory to the container, and uses the --secret flag to attach the db_credentials secret to the container. The -e flags expose the environment variables within the container.

Advantages of this approach:

  • Enhanced Security: The sensitive data is stored in a secure, encrypted format within Docker's secret store, preventing accidental exposure.
  • Improved Management: Docker secrets are easier to manage and update compared to hard-coded values in the Dockerfile.
  • Flexibility: You can easily update the secret without rebuilding the container image.

Additional Tips:

  • Centralized Secret Management: Use a dedicated secret management tool like HashiCorp Vault or AWS Secrets Manager for storing and managing sensitive data at scale.
  • Rotation: Rotate secrets regularly to enhance security.
  • Permissions: Grant only authorized users access to manage and access secrets.

By leveraging Docker secrets and environment variables, you can securely manage sensitive data and maintain the integrity of your application deployments. This approach fosters a safer environment while simplifying the management of sensitive information.