Docker Compose#
Docker Compose is the recommended way to run the full AI-Q blueprint stack (backend, frontend, and database) without managing individual processes.
Prerequisites#
Docker Engine and Docker Compose v2.
API keys for the models and tools you plan to use (refer to Installation – API Key Setup).
Ports
3000,8000, and5432available on your host.Enough disk space for Docker volumes and cached model artifacts.
Files and Directories#
The Docker Compose setup uses these files:
File |
Purpose |
|---|---|
|
Standard stack (LlamaIndex or FRAG backend) |
|
Environment variables for all services |
|
Template with all available variables |
|
PostgreSQL initialization script |
|
LlamaIndex backend config (default) |
|
Foundational RAG backend config |
Environment Setup#
Copy the example environment file and edit it:
cp deploy/.env.example deploy/.env
The sections below explain each group of variables.
API keys (required)#
Variable |
Required |
Description |
|---|---|---|
|
Yes |
NVIDIA API key for NIM model access. |
|
Conditional |
Web search provider key (required if using |
|
Conditional |
Web search provider key (required if using |
|
Conditional |
Web search provider key (required if using |
|
No |
Google Scholar paper search key (optional). |
API keys (optional)#
Variable |
Description |
|---|---|
|
Required only if your config uses OpenAI models directly. |
|
Required only if you enable the evaluation suite. |
|
Required only if you enable experiment tracking. |
Application Settings#
Variable |
Default |
Description |
|---|---|---|
|
|
Application environment ( |
|
|
Logging verbosity ( |
Backend Configuration#
Set BACKEND_CONFIG to select which workflow config the backend loads at startup. The compose stacks mount configs/ into the container at /app/configs.
Config path |
Description |
|---|---|
|
Default – LlamaIndex backend (no external RAG required). |
|
Foundational RAG mode (requires a running RAG Blueprint). |
Example in deploy/.env:
BACKEND_CONFIG=/app/configs/config_web_default_llamaindex.yml
Database Settings#
Choose one of the following database configurations.
PostgreSQL (recommended for all deployments):
NAT_JOB_STORE_DB_URL=postgresql+asyncpg://aiq:aiq_dev@postgres:5432/aiq_jobs # pragma: allowlist secret
AIQ_CHECKPOINT_DB=postgresql://aiq:aiq_dev@postgres:5432/aiq_checkpoints # pragma: allowlist secret
AIQ_SUMMARY_DB=postgresql+psycopg://aiq:aiq_dev@postgres:5432/aiq_jobs # pragma: allowlist secret
These are the default values used by the compose stack when the variables are unset.
SQLite (development only):
NAT_JOB_STORE_DB_URL=sqlite+aiosqlite:///./data/jobs.db
AIQ_CHECKPOINT_DB=/app/data/checkpoints.db
# AIQ_SUMMARY_DB defaults to sqlite+aiosqlite:///./summaries.db
When using SQLite, you can optionally remove the depends_on block for the aiq-agent service since the postgres container is no longer needed.
Artifact Storage#
Artifact metadata always uses the job database. Artifact bytes use SQL BLOB storage by default. The Compose stack does not provision an AWS S3 bucket; create the bucket externally, then set:
AIQ_ARTIFACT_BLOB_PROVIDER=s3
AIQ_ARTIFACT_S3_BUCKET=YOUR_BUCKET_NAME
AIQ_ARTIFACT_S3_REGION=us-west-2
AIQ_ARTIFACT_S3_PREFIX=artifacts/v1
The checked-in Compose stack also does not deploy MinIO. To run a local MinIO server with Docker:
export MINIO_CONTAINER=aiq-minio
export MINIO_ROOT_USER=YOUR_ACCESS_KEY
export MINIO_ROOT_PASSWORD=YOUR_SECRET_KEY
export AIQ_ARTIFACT_S3_BUCKET=YOUR_BUCKET_NAME
docker pull minio/minio
docker run --detach --name "$MINIO_CONTAINER" \
--publish 9000:9000 --publish 9001:9001 \
--env MINIO_ROOT_USER --env MINIO_ROOT_PASSWORD \
--volume aiq-minio-data:/data \
minio/minio server /data --console-address ":9001"
Open the MinIO console at http://localhost:9001 and create the bucket named by
AIQ_ARTIFACT_S3_BUCKET. Then add the same bucket and credentials to deploy/.env.
With Docker Desktop, the backend container reaches the host through
host.docker.internal:
AIQ_ARTIFACT_BLOB_PROVIDER=s3
AIQ_ARTIFACT_S3_BUCKET=YOUR_BUCKET_NAME
AIQ_ARTIFACT_S3_ENDPOINT_URL=http://host.docker.internal:9000
AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY
AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
For another environment, replace the endpoint with an address reachable from the
aiq-agent container.
The bucket is required when the provider is s3. Endpoint, region, and prefix are
optional; leave the endpoint unset for AWS S3, and the prefix defaults to
artifacts/v1. Configure credentials through workload identity, deployment secrets, or
the standard AWS credential chain. When the provider is s3, artifact bytes are stored
in the configured bucket and SQL stores artifact metadata only.
Frontend Runtime Settings#
Variable |
Default |
Description |
|---|---|---|
|
|
Backend API URL as seen from the frontend container. |
Dask Worker Settings#
Variable |
Default |
Description |
|---|---|---|
|
|
Number of Dask workers for background job processing. |
|
|
Number of threads per Dask worker. |
|
|
Dask log level (reduce noise). |
Standard Stack#
Build and Run Locally#
From the repository root:
cd deploy/compose
docker compose --env-file ../.env -f docker-compose.yaml up -d --build
This starts three services:
Service |
Container name |
Port |
Description |
|---|---|---|---|
|
|
8000 |
Backend API server with embedded Dask cluster |
|
|
3000 |
Next.js web UI |
|
|
5432 |
PostgreSQL database |
Open http://localhost:3000 to access the web UI.
Use Pre-Built NGC Images#
To skip the local build and pull pre-built images from the NGC container registry:
# Log in to the container registry
docker login nvcr.io
# Run with pre-built images (no --build flag)
cd deploy/compose
BACKEND_IMAGE=nvcr.io/nvidia/blueprint/aiq-agent:2.0.0 \
FRONTEND_IMAGE=nvcr.io/nvidia/blueprint/aiq-frontend:2.0.0 \
docker compose --env-file ../.env -f docker-compose.yaml up -d
You can also add the image variables to deploy/.env instead of passing them on the command line:
BACKEND_IMAGE=nvcr.io/nvidia/blueprint/aiq-agent:2.0.0
FRONTEND_IMAGE=nvcr.io/nvidia/blueprint/aiq-frontend:2.0.0
Release Build#
To build the production (release) image instead of the development image:
cd deploy/compose
BUILD_TARGET=release docker compose --env-file ../.env -f docker-compose.yaml up -d --build
The release image excludes the CLI and debug UI. Refer to Docker Build System for details on build targets.
Port Configuration#
If the default ports conflict with other services, override them in deploy/.env:
Variable |
Default |
Description |
|---|---|---|
|
|
Backend API host port |
|
|
Frontend UI host port |
PORT=8100 docker compose --env-file ../.env -f docker-compose.yaml up -d
Note: The backend API always runs on port 8000 inside the container. The PORT variable only changes the host port mapping.
Common conflicts:
The NVIDIA RAG Blueprint
page-elementsservice uses ports 8000–8002. SetPORT=8100to avoid this.Other development servers may occupy ports 8000, 8080, or 3000.
Foundational RAG (FRAG) Integration#
If you switch the backend to configs/config_web_frag.yml, you must run a compatible RAG server and ingest server separately and set these variables in deploy/.env:
RAG_SERVER_URL=http://rag-server:8081/v1
RAG_INGEST_URL=http://ingestor-server:8082/v1
Deploy the RAG services using the NVIDIA RAG Blueprint Docker guides:
Cross-Stack Networking#
When AI-Q and RAG are deployed as separate Docker Compose stacks, the AI-Q backend cannot resolve RAG service names (rag-server, ingestor-server) because the containers are on different Docker networks.
Connect the AI-Q backend container to the RAG network after both stacks are running:
docker network connect nvidia-rag aiq-agent
Then use the RAG service names directly in deploy/.env:
RAG_SERVER_URL=http://rag-server:8081/v1
RAG_INGEST_URL=http://ingestor-server:8082/v1
This must be re-run if the aiq-agent container is recreated (for example, after docker compose down && up).
Database Setup#
PostgreSQL (default)#
The compose stack includes a PostgreSQL 16 container (postgres:16-alpine). On first startup with a fresh volume, the init-db.sql script runs automatically and:
Creates the
aiq_checkpointsdatabase (theaiq_jobsdatabase is created by thePOSTGRES_DBenvironment variable).Grants permissions to the
aiquser.Creates the
job_infotable inaiq_jobswith performance indices.
Tables created automatically by the application at runtime:
job_events– created byevent_store.pyusing SQLAlchemy.LangGraph checkpoint tables – created by
AsyncPostgresSaver.summaries– created bysummary_store.pyif not present.
The PostgreSQL healthcheck verifies both aiq_jobs and aiq_checkpoints databases are ready before the backend starts.
SQLite Alternative#
For lightweight development without PostgreSQL, configure SQLite connection strings in deploy/.env (refer to Database Settings above). No init-db.sql is needed – the application creates SQLite files on demand.
Volume Mounts#
Volume |
Mount point |
Purpose |
|---|---|---|
|
|
Workflow configuration files |
|
|
LlamaIndex persistence (ChromaDB), SQLite databases |
|
|
PostgreSQL data directory |
Stopping and Cleanup#
cd deploy/compose
# Stop containers (preserves data volumes)
docker compose --env-file ../.env -f docker-compose.yaml down
# Stop and remove volumes (deletes all database data)
docker compose --env-file ../.env -f docker-compose.yaml down -v
Troubleshooting#
Check Container Logs#
docker logs aiq-agent -f
docker logs aiq-blueprint-ui -f
docker logs aiq-postgres -f
Verify the Backend Is Healthy#
curl http://localhost:8000/health
Connect to the Database#
docker exec -it aiq-postgres psql -U aiq -d aiq_jobs
Rebuild Without Cache#
If containers fail to start or you suspect stale build layers:
cd deploy/compose
docker compose --env-file ../.env -f docker-compose.yaml down
docker compose --env-file ../.env -f docker-compose.yaml build --no-cache
docker compose --env-file ../.env -f docker-compose.yaml up -d
Common Issues#
Symptom |
Cause |
Fix |
|---|---|---|
Backend fails to start |
Missing API keys in |
Verify |
Frontend shows connection error |
Backend not yet ready |
Wait for the backend healthcheck to pass; check |
Port already in use |
Another service occupies 3000, 8000, or 5432 |
Override with |
Database connection refused |
PostgreSQL not healthy |
Check |
FRAG mode fails to connect to RAG |
Separate Docker networks |
Run |