Managing Secrets and Config with Docker Env Vars

Updated May 2026
Environment variables are the primary mechanism for configuring Dockerized AI agents without hardcoding values into container images. They control everything from model endpoints and database connections to API keys and logging levels. A disciplined approach to environment variable management keeps your configurations portable, your secrets safe, and your deployments reproducible across development, staging, and production environments.

AI agent stacks typically need three categories of configuration: service connection URLs (model endpoints, database addresses, cache servers), operational settings (log levels, batch sizes, timeout values), and secrets (API keys, database passwords, access tokens). Each category has different security requirements and update frequencies, and your environment variable strategy should handle all three appropriately. These steps walk through the complete lifecycle from initial configuration to production secret management.

Define Environment Variables in Your Compose File

The environment key under a Compose service definition accepts a list of KEY=VALUE pairs that Docker injects into the container at startup. Use this for non-sensitive configuration that does not need to change between environments or that you want to version-control alongside your Compose file. Examples include MODEL_ENDPOINT set to http://ollama:11434, LOG_LEVEL set to info, and AGENT_MAX_TOKENS set to 4096.

Environment variables defined in the Compose file are visible in version control, which makes them auditable and easy to review in pull requests. This is a feature, not a bug, for non-sensitive values. Your team can see exactly what configuration each service uses without inspecting running containers or external configuration stores.

Docker Compose supports variable interpolation using the $VARIABLE or ${VARIABLE} syntax inside the Compose file. This lets you reference host environment variables or values from a .env file in your service definitions. For example, setting a service image to myregistry/${IMAGE_TAG} lets you control the deployed version by changing IMAGE_TAG in your .env file or shell environment without modifying the Compose file itself.

When a service needs many environment variables, consider using the environment key for critical operational settings and moving less frequently changed defaults into the container image via Dockerfile ENV instructions. The Compose environment key overrides any ENV values set in the Dockerfile, so you can set sensible defaults in the image and override only what changes between environments.

Use .env Files for Local Development

A .env file in the same directory as your Compose file is automatically loaded by Docker Compose. Values in this file are available for variable interpolation in the Compose file and can be passed to containers using the env_file directive. This automatic loading makes .env files the simplest way to manage environment-specific configuration.

Create separate .env files for each environment: .env.development, .env.staging, and .env.production. Each file contains the same variable names with environment-appropriate values. For development, MODEL_ENDPOINT might point to a local Ollama instance. For production, it might point to a load-balanced vLLM cluster. Switch between environments by copying the appropriate file to .env or using the --env-file flag with docker compose.

Add .env to your .gitignore file immediately. The .env file often contains database passwords, API keys, and other sensitive values that should never appear in version control. Instead, create a .env.example file that lists all required variables with placeholder values and commit that to your repository. New team members copy .env.example to .env and fill in their own values.

The env_file directive in a Compose service definition loads variables from a specified file directly into the container environment. Unlike the top-level .env file (which is for Compose variable interpolation), env_file sends values straight to the container. You can specify multiple env_file entries to layer configuration from different sources, with later files overriding values from earlier ones.

Separate Secrets from Configuration

Not all environment variables are equal. A LOG_LEVEL setting has no security implications, but a DATABASE_PASSWORD or OPENAI_API_KEY provides access to critical resources. Mixing secrets with general configuration in the same .env file makes it harder to apply appropriate access controls and increases the risk of accidental exposure through log files, error messages, or container inspection.

Create a dedicated secrets file (like .env.secrets) that contains only sensitive values. Set restrictive file permissions (chmod 600) so only the service account running Docker can read it. Reference this file with a separate env_file entry in your Compose service. This separation lets you manage secrets with different backup, rotation, and access policies than general configuration.

Never log or print environment variables that contain secrets. A common mistake in AI agent code is logging the full configuration at startup for debugging purposes. If your startup logging includes all environment variables, your API keys and database passwords appear in container logs that may be stored in a centralized logging system accessible to your entire team. Log only non-sensitive variable names and mask or omit values for anything containing key, secret, password, or token in the variable name.

Rotate secrets on a regular schedule and after any suspected exposure. Design your agent to handle secret rotation gracefully by either re-reading environment variables periodically or accepting configuration reload signals. If rotating a secret requires restarting the container, plan for brief downtime or use a rolling restart strategy to maintain service availability during rotation.

Use Docker Secrets for Sensitive Data

Docker secrets provide a more secure alternative to environment variables for sensitive data. Instead of passing secrets as environment variables (which are visible through docker inspect and /proc/environ inside the container), Docker mounts secrets as files in /run/secrets/ inside the container. These files exist only in memory and are never written to disk on the host or inside the container filesystem.

Define secrets in your Compose file using the top-level secrets section. Each secret references either a file on the host (using the file key) or an environment variable (using the environment key). Services that need the secret declare it in their secrets section, and Docker mounts the secret file into the container at /run/secrets/secret_name.

Your agent code needs to read secrets from files instead of environment variables when using Docker secrets. Most database drivers and API clients accept connection strings or credentials from files with minor configuration changes. For PostgreSQL, use the PGPASSFILE environment variable to point to a file containing the password. For custom agent code, read the file at /run/secrets/api_key and strip any trailing whitespace or newline characters.

Docker secrets in Compose v3+ with the file driver are straightforward for single-host deployments. For Docker Swarm deployments, secrets are encrypted at rest and in transit between swarm nodes. While most AI agent stacks run on single hosts with Compose rather than Swarm, understanding the Swarm secrets model is useful if you later scale to a multi-node deployment.

Validate Configuration at Container Startup

A missing or misconfigured environment variable can cause your agent to crash hours into operation when it first tries to use the missing value. Catch these errors immediately by validating all required environment variables at container startup before your agent begins processing requests.

Write a validation function that checks for the presence of every required variable, verifies that URL-type variables have valid formats, confirms that numeric variables contain valid numbers within expected ranges, and tests that file paths referenced by variables actually exist. Run this function as the first operation in your agent entrypoint script.

For critical connectivity settings like DATABASE_URL and MODEL_ENDPOINT, go beyond checking that the variable exists. Attempt a test connection during startup validation. Try connecting to the database and running a simple query. Send a health check request to the model endpoint. If these connections fail at startup, the agent fails immediately with a clear error message rather than appearing healthy and then failing on the first real request.

Print a sanitized configuration summary during startup that lists all configuration variables with their values, masking any secrets. This summary in the container logs serves as documentation of exactly what configuration the container started with, which is invaluable for debugging production issues days or weeks after deployment. Include the variable source (Compose file, .env file, Docker secret, or default value) for each variable so you can trace where a value came from.

Key Takeaway

Use the Compose environment key for non-sensitive defaults, .env files for environment-specific values, separate secret files with restricted permissions for credentials, and always validate that all required variables are present and correct at container startup.