Docker Deployment
This page covers deploying AutoMem using Docker Compose for local development and self-hosted production environments. Docker Compose provides a complete, isolated stack with FalkorDB, Qdrant, and the Flask API running in containers with persistent volumes.
For cloud deployment on Railway, see Railway Deployment. For environment variable reference across all deployment types, see the Configuration Reference.
Service Architecture
Section titled “Service Architecture”Docker Compose orchestrates four services defined in docker-compose.yml: the Flask API, FalkorDB graph database, Qdrant vector store, and an optional FalkorDB browser for visualization.
graph TB
subgraph host["Host Machine"]
Make["make dev<br/>docker-compose up"]
subgraph docker["Docker Network<br/>automem_default"]
API["memory-service<br/>app.py<br/>localhost:8001"]
Falkor["falkordb<br/>localhost:6379"]
QdrantLocal["qdrant<br/>localhost:6333"]
end
subgraph volumes["Docker Volumes"]
FalkorVol["falkordb_data<br/>/var/lib/falkordb/data"]
QdrantVol["qdrant_data<br/>/qdrant/storage"]
end
end
subgraph tools["Development Tools"]
Curl["curl<br/>localhost:8001"]
Python["Python Scripts<br/>scripts/"]
Tests["pytest<br/>tests/"]
end
Make --> API
Make --> Falkor
Make --> QdrantLocal
API --> Falkor
API --> QdrantLocal
Falkor --> FalkorVol
QdrantLocal --> QdrantVol
Curl --> API
Python --> API
Tests --> API
Service Details
Section titled “Service Details”| Service | Image/Build | Ports | Purpose | Health Check |
|---|---|---|---|---|
flask-api | Built from Dockerfile | 8001 | AutoMem Flask API with background workers | None (depends on FalkorDB health) |
falkordb | falkordb/falkordb:latest | 6379 (Redis), 3000 (UI) | Graph database (canonical memory storage) | redis-cli ping every 10s |
qdrant | qdrant/qdrant:v1.11.3 | 6333 | Vector search database (optional) | None (service_started) |
falkordb-browser | falkordb/falkordb-browser:latest | 3001 | Web-based graph visualization | None (profile-gated) |
Volume Configuration
Section titled “Volume Configuration”Docker Compose defines three named volumes for persistent data and one bind mount for source code. This ensures data survives container restarts and enables hot-reload during development.
Volume Persistence Strategy
Section titled “Volume Persistence Strategy”| Volume | Container Path | Purpose | Persistence Level | Backup Strategy |
|---|---|---|---|---|
falkordb_data | /data | RDB snapshots + AOF (append-only file) | High (every 60s or 1 key change) | Export via redis-cli SAVE to /backups |
qdrant_data | /qdrant/storage | Vector collections + write-ahead log | High (write-ahead log) | Export via Qdrant API to /backups |
fastembed_models | /root/.config/automem/models | Downloaded ONNX embedding models | Medium (cache, re-downloadable) | Not backed up (excluded in .gitignore) |
. (bind mount) | /app | Source code for hot-reload | N/A (host filesystem) | Git repository |
./backups/falkordb | /backups | Manual RDB exports | N/A (host filesystem) | Excluded in .gitignore |
./backups/qdrant | /backups | Manual snapshot exports | N/A (host filesystem) | Excluded in .gitignore |
FalkorDB Persistence Configuration
Section titled “FalkorDB Persistence Configuration”FalkorDB runs with aggressive persistence enabled via REDIS_ARGS:
--save 60 1: Create RDB snapshot every 60 seconds if at least 1 key changed--appendonly yes: Enable AOF (append-only file) for durability--appendfsync everysec: Sync AOF to disk every second--dir /data: Store persistence files in/data(mounted volume)
This configuration prioritizes data safety over performance, suitable for development where memory operations should not be lost on container restart.
Environment Variables
Section titled “Environment Variables”The Flask API service accepts environment variables for configuration. Most have sensible defaults for local development.
Required Environment Variables
Section titled “Required Environment Variables”| Variable | Docker Compose Default | Purpose | Notes |
|---|---|---|---|
PORT | 8001 | Flask API port | Must match container port mapping |
AUTOMEM_API_TOKEN | ${AUTOMEM_API_TOKEN:-test-token} | Client authentication | Set via shell or .env |
ADMIN_API_TOKEN | ${ADMIN_API_TOKEN:-test-admin-token} | Admin endpoint authentication | Set via shell or .env |
FALKORDB_HOST | falkordb | FalkorDB service name | Docker internal DNS resolution |
FALKORDB_PORT | 6379 | FalkorDB port | Standard Redis port |
Optional Configuration (with defaults)
Section titled “Optional Configuration (with defaults)”| Variable | Docker Compose Default | Purpose | Notes |
|---|---|---|---|
FLASK_ENV | development | Flask environment mode | Enables debug mode, hot-reload |
FLASK_DEBUG | "1" | Flask debug flag | Enables detailed error pages |
FALKORDB_PASSWORD | ${FALKORDB_PASSWORD:-} | FalkorDB authentication | Empty by default (no auth) |
QDRANT_URL | http://qdrant:6333 | Qdrant endpoint | Docker internal URL |
QDRANT_API_KEY | ${QDRANT_API_KEY:-} | Qdrant authentication | Not required for local Qdrant |
OPENAI_API_KEY | ${OPENAI_API_KEY:-} | OpenAI API access | Falls back to placeholder embeddings |
EMBEDDING_PROVIDER | ${EMBEDDING_PROVIDER:-auto} | Provider selection | `auto |
AUTOMEM_MODELS_DIR | /root/.config/automem/models | FastEmbed model cache | Must match volume mount path |
Accessing Variables
Section titled “Accessing Variables”Environment variables can be set three ways (in order of precedence):
- Process environment:
export OPENAI_API_KEY=sk-...before runningdocker compose up .envfile: Create.envin project root withOPENAI_API_KEY=sk-...- Docker Compose defaults: Fallback values in
docker-compose.yml
Service Dependencies and Health Checks
Section titled “Service Dependencies and Health Checks”Docker Compose manages startup order and readiness using depends_on conditions and health checks. This prevents the Flask API from attempting to connect to FalkorDB before it’s ready.
Health Check Details
FalkorDB is the only service with a health check defined:
- Test command:
redis-cli ping(expectsPONGresponse) - Interval: Check every 10 seconds
- Timeout: Fail if command doesn’t respond within 5 seconds
- Retries: Attempt 5 times before marking unhealthy
- Initial delay: No explicit
start_period, begins checking immediately
The Flask API waits for condition: service_healthy, ensuring FalkorDB is accepting connections before the API attempts to connect.
Qdrant uses condition: service_started, meaning the Flask API starts as soon as the Qdrant container starts (not waiting for full initialization). The API handles Qdrant connection failures gracefully via the graceful degradation pattern — Qdrant being unavailable results in "qdrant": "not_configured" in /health but does not prevent the service from running.
Networking
Section titled “Networking”Docker Compose creates an isolated network where services communicate using service names as hostnames. External clients access the Flask API via localhost port mapping.
Port Mappings
Section titled “Port Mappings”| Container Port | Host Port | Service | Protocol | Purpose |
|---|---|---|---|---|
| 8001 | 8001 | flask-api | HTTP | AutoMem REST API |
| 6379 | 6379 | falkordb | TCP (Redis protocol) | FalkorDB graph queries |
| 3000 | 3000 | falkordb | HTTP | FalkorDB built-in web UI |
| 6333 | 6333 | qdrant | HTTP | Qdrant vector search API |
| 3001 | 3001 | falkordb-browser | HTTP | FalkorDB Browser (optional) |
Internal DNS Resolution
Section titled “Internal DNS Resolution”Flask API connects to dependencies using service names:
FALKORDB_HOST=falkordbresolves to thefalkordbcontainer’s internal IPQDRANT_URL=http://qdrant:6333resolves to theqdrantcontainer’s internal IP
Docker Compose automatically creates a DNS entry for each service name on the automem_default bridge network. This differs from Railway’s .railway.internal hostnames (see Railway Deployment).
Development Workflow
Section titled “Development Workflow”The Makefile provides commands for common Docker Compose operations. These commands handle container lifecycle, testing, and cleanup.
Makefile Commands Reference
Section titled “Makefile Commands Reference”| Command | Underlying Action | Purpose | Data Loss Risk |
|---|---|---|---|
make dev | docker compose up --build | Start all services, rebuild images if Dockerfile changed | None |
make logs | docker compose logs -f flask-api | Follow Flask API logs in real-time | None |
make test-integration | Start services, run pytest with integration tests, keep running | Run full test suite against local Docker stack | None (uses test tokens) |
make clean | docker compose down -v | Stop containers, remove volumes | High — deletes all memory data |
make stop | docker compose down | Stop containers, preserve volumes | None |
Starting Services
Section titled “Starting Services”make devThe --build flag ensures the Flask API image is rebuilt if Dockerfile or requirements.txt changed.
Viewing Logs
Section titled “Viewing Logs”make logs# or for all services:docker compose logs -fRunning Integration Tests
Section titled “Running Integration Tests”The make test-integration command orchestrates a full test run:
- Starts Docker Compose with test tokens (
AUTOMEM_API_TOKEN=test-token,ADMIN_API_TOKEN=test-admin-token) - Waits 5 seconds for service initialization
- Runs pytest with
AUTOMEM_RUN_INTEGRATION_TESTS=1environment variable - Leaves services running for debugging
Stopping and Cleanup
Section titled “Stopping and Cleanup”# Stop containers, preserve data volumes:make stop
# Stop containers AND delete all data volumes:make cleanHot-Reload During Development
Section titled “Hot-Reload During Development”The Flask API container mounts the project directory as a volume, enabling hot-reload:
- Edit any Python file in the project
- Flask detects the change (via
FLASK_DEBUG=1) - API automatically reloads within ~2 seconds
- No need to restart containers
Production Considerations
Section titled “Production Considerations”Docker Compose is optimized for development. Production deployments require security hardening, different persistence strategies, and monitoring.
Development vs. Production Configuration
Section titled “Development vs. Production Configuration”| Aspect | Docker Compose (Dev) | Production Recommendations |
|---|---|---|
| Debug Mode | FLASK_DEBUG=1, verbose logging | Disable debug, set LOG_LEVEL=INFO or WARNING |
| API Tokens | Defaults to test-token, test-admin-token | Generate cryptographically secure tokens (32+ chars) |
| Port Exposure | All ports mapped to localhost | Use reverse proxy (nginx, Traefik), expose only necessary ports |
| Volume Backups | Manual exports to ./backups/ | Automated backups to S3/remote storage (see Backup & Recovery) |
| Resource Limits | Unlimited | Set deploy.resources.limits in docker-compose.yml |
| Restart Policy | restart: unless-stopped | Use restart: always with health checks |
| FalkorDB Persistence | Aggressive (save 60 1) | Balance between durability and performance |
| SSL/TLS | HTTP only | Terminate SSL at reverse proxy or use Traefik |
| Monitoring | Docker logs | External monitoring (Prometheus, health checks) |
When to Use Docker Compose vs. Railway
Section titled “When to Use Docker Compose vs. Railway”| Scenario | Recommended Deployment |
|---|---|
| Single developer, local-only access | Docker Compose on local machine |
| Team collaboration, remote access needed | Railway (see Railway Deployment) |
| Self-hosted production, existing infrastructure | Docker Compose with reverse proxy + backups |
| Prototyping, short-term experiments | Docker Compose (no cloud costs) |
| Production with minimal ops overhead | Railway (managed backups, monitoring) |
| Air-gapped environments, strict data locality | Docker Compose on self-hosted infrastructure |
| Multi-region deployment | Multiple Railway projects or Kubernetes |
Migrating from Docker Compose to Railway
Section titled “Migrating from Docker Compose to Railway”Data can be migrated using backup/restore scripts:
- Export from Docker Compose:
Terminal window python scripts/backup_automem.py --output ./backups/ - Import to Railway:
- Use GitHub Actions backup workflow to populate Railway from exported snapshots
- See Backup & Recovery for full restore procedures