Here is a secure, production-ready docker-compose.yml for LiteLLM that implements local network binding, explicit CPU/memory constraints, non-root user execution, read-only container filesystems, and strict environment variable handling.
1. Project Directory Structure
Set up your project directory layout as follows before starting the container:
Plaintext
litellm-project/├── .env # Private secrets (DO NOT COMMIT)├── config.yaml # LiteLLM routing & proxy settings└── docker-compose.yml # Hardened container stack
2. File Configurations
.env (Secrets File)
Create a .env file in the same directory. This keeps sensitive API keys isolated from your repository code.
Ini, TOML
# Upstream LLM API KeysOPENAI_API_KEY=sk-proj-your-actual-openai-api-key-hereANTHROPIC_API_KEY=sk-ant-your-actual-anthropic-api-key-here# LiteLLM Administration Key (Used for generating virtual keys and proxy admin)LITELLM_MASTER_KEY=sk-master-litellm-secret-key-change-this
config.yaml (LiteLLM Model & Security Config)
Define your backend models and security settings:
YAML
model_list: - model_name: gpt-4o litellm_params: model: gpt-4o api_key: os.environ/OPENAI_API_KEY - model_name: claude-3-5-sonnet litellm_params: model: claude-3-5-sonnet-20241022 api_key: os.environ/ANTHROPIC_API_KEYgeneral_settings: master_key: os.environ/LITELLM_MASTER_KEY # Enable database / budget features if using LiteLLM database mode
docker-compose.yml (Hardened Deployment)
YAML
version: '3.8'services: litellm: image: ghcr.io/berriai/litellm:main-v1.59.0 container_name: litellm-proxy restart: unless-stopped # 1. Local Network Binding (Prevents exposure on public/LAN interfaces) ports: - "127.0.0.1:4000:4000" # 2. Command Execution with Config Mapping command: [ "--config", "/app/config.yaml", "--port", "4000", "--num_workers", "2" ] # 3. Mount Config & Read-Only Temp Volume volumes: - ./config.yaml:/app/config.yaml:ro - tmp_data:/tmp # 4. Environment Variables loaded from .env env_file: - .env # 5. Security & Isolation Enhancements read_only: true # Prevents malicious writes to the container filesystem user: "1000:1000" # Runs as a non-root user security_opt: - no-new-privileges:true # Blocks privilege escalation attacks cap_drop: - ALL # Drops all Linux kernel capabilities # 6. Resource Limits (Prevents container from starving host CPU/RAM) deploy: resources: limits: cpus: '1.5' memory: 1536M reservations: cpus: '0.25' memory: 256M # 7. Health Check healthcheck: test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:4000/health/liveliness')"] interval: 30s timeout: 5s retries: 3 start_period: 15svolumes: tmp_data: driver: local
Step-by-Step Deployment Instructions
1.Set Secure File Permissions for Secrets:
Ensure the .env file is accessible only by your host user:
chmod 600 .env
Verification: Run ls -l .env and confirm the permission bit shows -rw-------.
2.Start the LiteLLM Proxy Stack:
Launch the container in detached mode:
docker compose up -d
Verification: Run docker compose ps to verify the container state is Up (healthy).
3.Test Local Binding Security:
Verify that the proxy endpoints respond on 127.0.0.1 using your configured master key:
Bash
curl -i http://127.0.0.1:4000/health/readiness \ -H "Authorization: Bearer sk-master-litellm-secret-key-change-this"
Verification: Expect an HTTP/1.1 200 OK response with {"status": "connected"}.