Infrastructure Management

This guide covers the full lifecycle of Sagewai's infrastructure services: starting and stopping containers, monitoring health, managing data volumes, running database migrations, and running without containers when needed.

Service dependency graph

Services start in dependency order. If a dependency is not healthy, downstream services will not start correctly.

Loading diagram...

PostgreSQL and Redis have no dependencies and start independently. Milvus requires etcd and MinIO to be healthy first. NebulaGraph services must start in order: metad, then storaged, then graphd. All observability data flows into Grafana.

Starting services

# Full stack (all services + observability)
make infra

# Core only (PostgreSQL + Redis, ~200 MB RAM)
make infra-core

# Full stack with containerized application backends
make dev-up

Stopping services

# Stop all containers, keep data volumes
make down
# equivalent to:
docker compose down

# Stop and delete all data volumes (fresh start)
docker compose down -v

Monitoring

# Check running containers and health status
docker compose ps

# Follow logs for one service
docker compose logs -f milvus

# Follow logs for all services
docker compose logs -f

# Check health endpoints
curl http://localhost:8000/api/v1/health/summary   # Admin API summary
curl http://localhost:8000/api/v1/health/detailed  # Detailed infrastructure health

Common operations

# Restart one service without rebuilding
docker compose restart milvus

# Rebuild and restart one service
docker compose up -d --build admin

# Scale workers horizontally
docker compose up -d --scale worker=3

# Check per-container resource usage
docker stats

Compose Specification compatibility

Sagewai's docker-compose.yml targets the Compose Specification, so it works with multiple container runtimes:

RuntimeCommandNotes
Docker Compose V2docker compose up -dDefault on modern Docker Desktop
Podman Composepodman-compose up -dDrop-in replacement
nerdctl (containerd)nerdctl compose up -dLightweight alternative

The version: field is optional in the Compose Spec and may be omitted.

Podman alternative

Podman is a rootless, daemonless runtime that works as a drop-in replacement for Docker.

Install:

# macOS
brew install podman podman-compose
podman machine init
podman machine start

# Linux (Ubuntu/Debian)
sudo apt install podman podman-compose

# Alias for Makefile compatibility
alias docker=podman
alias docker-compose=podman-compose

Key differences from Docker:

FeatureDockerPodman
DaemonRequires dockerdDaemonless
Root accessRoot by defaultRootless by default
Socket/var/run/docker.sockUser-level socket
Composedocker composepodman-compose
GPU support--gpus all--device nvidia.com/gpu=all

Start Sagewai with Podman:

podman-compose -f docker-compose.yml up -d

# With the alias set above, Makefile targets work unchanged:
make infra

Volume permissions: Podman runs rootless by default. If you are on SELinux, add the :Z suffix to volume mounts:

volumes:
  - ./data:/var/lib/postgresql/data:Z

Native setup (no containers)

Use this when containers are not available or not practical.

PostgreSQL

# macOS
brew install postgresql@15
brew services start postgresql@15
createdb sagewai

# Ubuntu/Debian
sudo apt install postgresql-15
sudo -u postgres createdb sagewai

Set the connection string:

export DATABASE_URL=postgresql://localhost:5432/sagewai

Redis

# macOS
brew install redis
brew services start redis

# Ubuntu/Debian
sudo apt install redis-server
sudo systemctl start redis
export REDIS_URL=redis://localhost:6379

Milvus (optional)

Required for vector search. Without it, Sagewai falls back to in-memory vectors, which is fine for development.

Option A: Standalone binary

curl -sfL https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh | bash

Option B: Zilliz Cloud (managed)

Sign up at cloud.zilliz.com and set:

export MILVUS_HOST=your-cluster.zillizcloud.com
export MILVUS_PORT=19530

NebulaGraph (optional)

Required for knowledge graphs. Without it, Sagewai falls back to in-memory graphs, which is sufficient for development. Download from nebula-graph.io.

Data volume management

Where data lives

ServiceVolume nameContents
PostgreSQLsagewai_postgres_dataWorkflows, runs, workers, audit logs
Milvussagewai_milvus_dataVector embeddings
MinIOsagewai_minio_dataMilvus object storage
etcdsagewai_etcd_dataMilvus metadata
NebulaGraphsagewai_nebula_*Graph data and metadata
RedisIn-memoryCache only (no persistence by default)

Backup

# Plain SQL dump
docker compose exec postgres pg_dump -U sagewai sagewai > backup.sql

# Compressed custom-format dump
docker compose exec postgres pg_dump -U sagewai -Fc sagewai > backup.dump

Restore

# From plain SQL dump
docker compose exec -T postgres psql -U sagewai sagewai < backup.sql

# From compressed dump
docker compose exec -T postgres pg_restore -U sagewai -d sagewai < backup.dump

Full reset

docker compose down -v
make infra
make db-upgrade
make db-seed  # optional: load demo data

Or use the combined shortcut:

make db-fresh  # drop + migrate + seed in one command

Database migrations

Migrations are managed by Alembic. Migration files live in sagewai/db/migrations/versions/.

# Apply pending migrations
make db-upgrade

# Drop schema, recreate, and migrate
make db-reset

# Seed with demo data
make db-seed

# Drop + migrate + seed in one step
make db-fresh

Graceful degradation

Sagewai continues to function when optional services are absent:

Missing serviceFallbackLimitation
MilvusIn-memory vectorsData lost on restart — development only
NebulaGraphIn-memory graphData lost on restart — development only
RedisDirect database queriesSlower response times, no caching
LocalStackLocal filesystemNo S3-compatible archival
Observability stackNo dashboardsAgents still run; no metrics or tracing

Minimum viable deployment: PostgreSQL only.

make infra-core    # starts PostgreSQL + Redis (~200 MB)
make db-upgrade    # apply migrations
make dev-native APP=admin  # start admin backend