Docker Environment File Q&A Guide
Docker Environment File Q&A Guide
📋 Table of Contents
❓ Common Issues
Issue 1: httpx.UnsupportedProtocol: Request URL is missing an 'http://' or 'https://' protocol
🔍 Root Cause:
- The
.envfile had quotes around URL values ("http://gateway.example.com/v1") - Docker reads these quotes as part of the actual value
- This results in the URL being
"http://gateway.example.com/v1"(with quotes) - HTTP clients cannot parse URLs that start with quotes
✅ Solution:
Remove quotes from environment variables in .env files when using Docker’s --env-file option.
❌ Incorrect:
AI_AUTH_KEY="Bearer sk-xxxxx"
AI_BASE_URL="http://gateway.example.com/v1"
HF_ENDPOINT="https://hf-mirror.com"
✅ Correct:
AI_AUTH_KEY=Bearer sk-xxxxx
AI_BASE_URL=http://gateway.example.com/v1
HF_ENDPOINT=https://hf-mirror.com
🔤 Quote Handling
When Docker Reads Environment Files
Different Tools Handle Quotes Differently:
| Tool | Quote Behavior | Example |
|---|---|---|
Shell (source .env) |
Strips quotes | API_KEY="value" → value |
Docker (--env-file) |
Preserves quotes | API_KEY="value" → "value" |
Node.js (dotenv) |
Strips quotes | API_KEY="value" → value |
Python (python-dotenv) |
Configurable | Depends on settings |
Best Practices for Docker
- Don’t use quotes in
.envfiles for Docker: ```properties✅ Good for Docker
DATABASE_URL=postgresql://user:pass@localhost/db API_KEY=sk-1234567890
❌ Avoid for Docker
DATABASE_URL=”postgresql://user:pass@localhost/db” API_KEY=”sk-1234567890”
2. **Use quotes only when values contain spaces:**
```properties
# ✅ When spaces are needed
APP_NAME=My Application Name
# or escape spaces
APP_NAME=My\ Application\ Name
🎯 Best Practices
Environment File Structure
# ===== API Configuration =====
API_BASE_URL=https://api.example.com/v1
API_KEY=your-api-key-here
API_TIMEOUT=30
# ===== Database Configuration =====
DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp
DB_USER=postgres
# ===== Feature Flags =====
ENABLE_DEBUG=false
ENABLE_LOGGING=true
Security Considerations
- Never commit
.envfiles with secrets - Use
.env.examplefor templates:# .env.example API_KEY=your-api-key-here DATABASE_URL=postgresql://user:pass@host:port/db - Validate environment variables in code: ```python import os
def validate_env(): required_vars = [‘API_KEY’, ‘BASE_URL’] missing = [var for var in required_vars if not os.getenv(var)] if missing: raise ValueError(f”Missing environment variables: {missing}”)
## 🔧 Troubleshooting
### Debug Environment Variables
**Check what Docker actually sees:**
```bash
docker run --env-file .env your-image env | grep YOUR_VAR
Debug in Python:
import os
print(f"Raw value: '{os.getenv('YOUR_VAR')}'")
print(f"Length: {len(os.getenv('YOUR_VAR', ''))}")
print(f"Starts with quote: {os.getenv('YOUR_VAR', '').startswith('\"')}")
Common Error Patterns
| Error | Likely Cause | Solution |
|---|---|---|
UnsupportedProtocol |
Quotes in URL | Remove quotes from .env |
ConnectionError |
Network isolation | Use --network host |
Invalid URL |
Missing protocol | Add http:// or https:// |
Empty variable |
Typo in variable name | Check spelling |
Testing Environment Setup
# Test environment file loading
docker run --rm --env-file .env alpine:latest sh -c 'echo "API_KEY=$API_KEY"'
# Test network connectivity
docker run --rm --network host alpine:latest ping -c 1 google.com
# Test DNS resolution
docker run --rm alpine:latest nslookup your-internal-domain.com
📝 Code Examples
Robust Environment Loading in Python
import os
from typing import Optional
class Config:
def __init__(self):
self.api_key = self._get_required_env('API_KEY')
self.base_url = self._get_required_env('BASE_URL')
self.timeout = int(self._get_env('TIMEOUT', '30'))
def _get_required_env(self, key: str) -> str:
value = os.getenv(key)
if not value:
raise ValueError(f"Required environment variable {key} is not set")
# Strip quotes if present (defensive programming)
return value.strip('"\'')
def _get_env(self, key: str, default: str) -> str:
return os.getenv(key, default).strip('"\'')
# Usage
config = Config()
Docker Compose with Environment Files
version: '3.8'
services:
app:
build: .
env_file:
- .env
environment:
- NODE_ENV=production
networks:
- app-network
# Use host network for internal services
# network_mode: host
networks:
app-network:
driver: bridge
🎉 Success Checklist
After applying fixes, verify:
- ✅ Environment variables load without quotes
- ✅ Network connectivity works (can reach APIs)
- ✅ No protocol errors in HTTP requests
- ✅ Application starts successfully
- ✅ All required environment variables are present
- ✅ No sensitive data in version control
💡 Pro Tip: Always test your Docker environment setup with a simple echo command before running complex applications to verify environment variables are loaded correctly.