Heimdall provides first-class Docker support with multi-stage builds and flexible database options.
Quick Start
Clone the repository
git clone https://github.com/modestnerd/heimdall.git
cd heimdall
Configure environment
Edit .env and set at least one AI provider key: ANTHROPIC_API_KEY = sk-ant-...
# or
OPENAI_API_KEY = sk-...
# or
OLLAMA_URL = http://localhost:11434
Start with Docker Compose
docker compose --profile postgres up -d
Docker Compose Profiles
Heimdall supports multiple database backends via Docker Compose profiles. Only activate one database at a time.
PostgreSQL (Recommended)
MySQL
MongoDB
docker compose --profile postgres up -d
PostgreSQL is the recommended and most tested database backend.
Building from Source
The Dockerfile uses a multi-stage build process:
Build Arguments
Argument Default Description DB_DRIVERpostgresDatabase driver: postgres, mysql, mongo, or sqlite INSTALL_SEMGREPtrueInstall Semgrep for enhanced static analysis
Custom Build
# Build with custom database driver
docker compose build --build-arg DB_DRIVER=mysql
# Build without Semgrep (smaller image)
docker compose build --build-arg INSTALL_SEMGREP= false
# Force rebuild
docker compose --profile postgres up -d --build
Environment Configuration
Required Variables
Anthropic (Recommended)
OpenAI
Ollama (Local)
ANTHROPIC_API_KEY = sk-ant-api03-...
Database Connection
The database URL format depends on your chosen profile:
DATABASE_URL = postgres://heimdall:heimdall@postgres:5432/heimdall
When using Docker Compose, use the service name (e.g., postgres, mysql, mongo) as the hostname, not localhost.
Security Keys
Generate secure keys for encryption and webhook verification:
# Encryption key for stored API keys
ENCRYPTION_KEY = $( openssl rand -hex 32 )
# Webhook signature verification
WEBHOOK_SECRET = $( openssl rand -hex 20 )
Add these to your .env file.
Docker Volumes
Heimdall requires access to the Docker socket for the Garmr sandbox:
volumes :
- /var/run/docker.sock:/var/run/docker.sock
Mounting the Docker socket grants the container access to create and manage other containers. Ensure proper network isolation in production environments.
Persistent Data
Database data is stored in named volumes:
volumes :
postgres-data : # PostgreSQL data
mysql-data : # MySQL data
mongo-data : # MongoDB data
To backup or migrate data:
# List volumes
docker volume ls
# Backup PostgreSQL data
docker run --rm -v heimdall_postgres-data:/data -v $( pwd ) :/backup \
alpine tar czf /backup/postgres-backup.tar.gz -C /data .
# Restore PostgreSQL data
docker run --rm -v heimdall_postgres-data:/data -v $( pwd ) :/backup \
alpine tar xzf /backup/postgres-backup.tar.gz -C /data
Health Checks
Heimdall includes built-in health checks:
healthcheck :
test : [ "CMD" , "curl" , "-f" , "http://localhost:8080/health" ]
interval : 30s
timeout : 10s
retries : 3
start_period : 10s
Check container health:
docker compose ps
docker inspect heimdall | jq '.[0].State.Health'
Troubleshooting
Container won’t start
Check logs
docker compose logs -f heimdall
Verify database is ready
docker compose ps
# Ensure database service shows "healthy"
Check environment variables
docker compose config
# Verify .env values are loaded correctly
Database connection fails
Common mistake: Using localhost instead of the service name in DATABASE_URL.
# ❌ Wrong (when using Docker Compose)
DATABASE_URL = postgres://heimdall:heimdall@localhost:5432/heimdall
# ✅ Correct
DATABASE_URL = postgres://heimdall:heimdall@postgres:5432/heimdall
Permission denied on Docker socket
# Add your user to the docker group
sudo usermod -aG docker $USER
# Log out and back in, then verify
docker ps
Out of memory errors
Increase Docker daemon memory limits:
# Docker Desktop: Settings > Resources > Memory (recommend 4GB+)
# Linux: Edit /etc/docker/daemon.json
{
"default-ulimits" : {
"memlock" : {
"Hard" : -1,
"Soft" : -1
}
}
}
Semgrep not working
Rebuild with Semgrep enabled:
docker compose build --build-arg INSTALL_SEMGREP= true --no-cache
docker compose up -d
Clean slate restart
This will delete all data, including scans and findings.
# Stop and remove containers, volumes, and images
docker compose down -v --rmi all
# Rebuild and start fresh
docker compose --profile postgres up -d --build
Development Workflow
For local development, use docker-compose.dev.yml to run only the database:
# Start only PostgreSQL
docker compose -f docker-compose.dev.yml up -d
# Run Heimdall locally
cargo run --bin heimdall
This allows faster iteration with hot reloading while keeping the database containerized.
Next Steps
Production Deployment Harden your deployment for production use
Reverse Proxy Setup Configure Nginx with TLS and SSE support