Complete guide for running Docling Pipelines pipelines with distributed execution using Prefect work pools and workers.
Distributed execution allows Docling Pipelines pipelines to process data across multiple machines or containers, enabling horizontal scaling and improved throughput. Instead of processing all batches on a single machine, work is distributed to multiple workers that execute batches in parallel.
Use distributed execution when:
Use default local execution when:
┌─────────────────┐
│ Your Machine │
│ (Submitter) │──┐
└─────────────────┘ │
│ │ Submit Flow
│ ↓
│ ┌──────────────────────────────────────┐
│ │ Prefect Server │
│ │ (Central Coordinator) │
│ └──────────────────────────────────────┘
│ │
│ ┌────────────┼────────────┐
│ ↓ ↓ ↓
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ │ Worker 1 │ │ Worker 2 │ │ Worker 3 │
│ └─────────────┘ └─────────────┘ └─────────────┘
│ ▲ ▲ ▲
│ │ │ │
│ └────────────┼────────────┘
│ │
│ ┌─────────────┐
└─────────────▶│ Storage │
│ (Local) │
└─────────────┘
Components:
USER_GUIDE_PIPELINE_SETUP.md)By default, Docling Pipelines runs in ephemeral mode with zero infrastructure setup.
When to use:
How to run:
# Just run - no setup needed
docling-pipelines --flow-file sample_flows/quickstart/complete_pipeline_ollama.json
Under the hood:
Environment variables:
PREFECT_MODE: Defaults to ephemeral (no need to set)PREFECT_API_URL requiredRun distributed execution on a single machine to understand work pools before moving to Docker.
When to use:
# Terminal 1: Start Prefect server
prefect server start
Server starts at http://localhost:4200. Open in browser to access Prefect UI.
# Terminal 2: Create a process work pool
prefect work-pool create docpipe-pool --type process
Verify:
prefect work-pool ls
# Terminal 2: Start worker
prefect worker start --pool docpipe-pool
# Terminal 3: Set environment variables
export PREFECT_MODE=server
export PREFECT_API_URL=http://localhost:4200/api
Critical: Without PREFECT_MODE=server, Docling Pipelines uses ephemeral mode and ignores work pool configuration.
Job stats store guidance for this setup:
DOCPIPE_STORAGE_BACKEND, DOCPIPE_FRAMEWORK_TYPE, and DOCPIPE_JOB_STATS_BASE_DIR can be set explicitly in work-pool env, but if they are omitted the worker inherits the submitter’s effective job-management configuration resolved from envJsonJobStatsStore can work for work-pool-process only when the submitter and worker share the same filesystem semanticsbase_dir paths depend on where the submitter and worker processes are startedDOCPIPE_JOB_STATS_BASE_DIR is propagated to workers as a resolved absolute path so workers do not reinterpret relative base_dir values differentlyPostgresJobStatsStoreDOCPIPE_POSTGRES_HOST, DOCPIPE_POSTGRES_PORT, DOCPIPE_POSTGRES_DB, DOCPIPE_POSTGRES_USER, and DOCPIPE_POSTGRES_PASSWORD unless explicitly overridden in work-pool envAdd work pool configuration to your flow JSON:
{
"flow_name": "distributed-local-pipeline",
"description": "Distributed execution using Prefect work pools",
"global_config": {
"doc_column": "content",
"storage": "in-memory",
"execute_type": "local",
"prefect": {
"batch_execution": {
"strategy": "work-pool-process",
"work_pool_name": "docpipe-pool",
"batch_storage": {
"type": "local",
"path": "/tmp/docpipe-batches"
}
}
}
},
"flow": [...]
}
# Terminal 3: Run the flow
docling-pipelines --flow-file your-flow.json
http://localhost:4200Work pool configuration is added to your flow JSON under global_config.prefect.batch_execution:
{
"global_config": {
"prefect": {
"batch_execution": {
"strategy": "work-pool-docker",
"work_pool_name": "docpipe-pool",
"batch_storage": {
"type": "s3",
"bucket": "my-docpipe-batches"
}
}
}
}
}
work-pool-process)Description: Executes batches as local processes without containerization.
Use cases:
Configuration:
{
"prefect": {
"batch_execution": {
"strategy": "work-pool-process",
"work_pool_name": "docpipe-pool",
"batch_storage": {
"type": "local",
"path": "/data/batches"
}
}
}
}
Requirements:
Work Pool Path Resolution:
The deployment_path configuration controls where Prefect workers look for your code. This is critical because the submitter (where you run docling-pipelines) and the worker (where batches execute) may have different filesystem layouts.
| Scenario | Submitter | Worker | Paths Same? | os.getcwd() Works? |
|---|---|---|---|---|
| Local dev (Steps 1-4 above) | Your machine | Same machine (subprocess) | ✅ Yes | ✅ Yes |
| Docker (docker-compose) | Your machine | Docker container | ❌ No | ❌ No |
Local Development Flow (os.getcwd() works):
path = os.getcwd() (e.g., /Users/.../docling-pipelines)/Users/.../docling-pipelinesDocker Flow (os.getcwd() breaks):
path = os.getcwd() (e.g., /Users/.../docling-pipelines)/Users/.../docling-pipelines/app/src/docpipeSolution:
The deployment_path parameter is optional:
None (default) → falls back to os.getcwd() → local dev worksLocal Development (no change needed):
{
"prefect": {
"batch_execution": {
"strategy": "work-pool-process",
"work_pool_name": "docpipe-pool"
}
}
}
Docker Compose (set deployment_path explicitly):
{
"prefect": {
"batch_execution": {
"strategy": "work-pool-process",
"work_pool_name": "docpipe-pool",
"deployment_path": "/app/src/docpipe"
}
}
}
This matches:
ENV PYTHONPATH=/app/srcPYTHONPATH: /app/srcJob stats store guidance:
DOCPIPE_STORAGE_BACKEND, DOCPIPE_FRAMEWORK_TYPE, and backend-specific settings, but if omitted the worker inherits the submitter’s effective job-management configurationJsonJobStatsStore, DOCPIPE_JOB_STATS_BASE_DIR should resolve to the same absolute shared path for submitter and workers instead of relying on cwd-relative resolutionDOCPIPE_JOB_STATS_BASE_DIR=/absolute/path/to/data/job_statsDOCPIPE_JOB_STATS_BASE_DIR=/app/data/job_statsPostgresJobStatsStoreDOCPIPE_POSTGRES_HOST, DOCPIPE_POSTGRES_PORT, DOCPIPE_POSTGRES_DB, DOCPIPE_POSTGRES_USER, and DOCPIPE_POSTGRES_PASSWORD environment variableswork-pool-docker)Description: Executes batches in Docker containers.
Use cases:
Worker Image vs Batch Execution Image:
image field)Configuration options:
| Option | Type | Default | Description |
|---|---|---|---|
image |
string | "docling-pipelines:latest" |
Docker image for batch execution (can include registry) |
image_pull_policy |
string | "Never" |
When to pull: "Never" (POC), "IfNotPresent" (prod), "Always" (latest) |
networks |
list[string] | [] |
Docker networks to connect to |
env |
dict | {} |
Environment variables for container |
Public Registries:
Public registries work by embedding the registry URL in the image name. No authentication required.
Image name format examples (replace with your actual registry and image):
docker.io/your-username/your-image:tag or your-username/your-image:tagghcr.io/your-org/your-image:tagyour-harbor.example.com/project/your-image:tagyour-registry.example.com/path/your-image:tagExample with Docker Hub:
{
"prefect": {
"batch_execution": {
"strategy": "work-pool-docker",
"work_pool_name": "docpipe-docker-pool",
"image": "myusername/docling-pipelines:v1.0.0",
"image_pull_policy": "IfNotPresent"
}
}
}
Example with GHCR:
{
"prefect": {
"batch_execution": {
"strategy": "work-pool-docker",
"image": "ghcr.io/myorg/docling-pipelines:v1.0.0",
"image_pull_policy": "Always"
}
}
}
Private Docker Registries:
Private registries require authentication configured on the worker host machine.
Setup steps:
docker login registry.example.com
# Enter username and password
{
"prefect": {
"batch_execution": {
"image": "registry.example.com/docpipe/runtime:v1.0.0",
"image_pull_policy": "IfNotPresent"
}
}
}
~/.docker/config.json on worker hostImportant notes:
image_pull_policy: "IfNotPresent" to reduce registry load"Never" with locally built imagesImage Pull Policy Guidance:
| Policy | Use Case | Behavior |
|---|---|---|
"Never" |
POC/local development | Never pulls, uses local image only. Fails if image not present. |
"IfNotPresent" |
Production (recommended) | Pulls only if image not cached locally. Efficient for stable versions. |
"Always" |
Latest/development | Always pulls from registry. Use for :latest tag or rapid iteration. |
Example with local storage:
{
"prefect": {
"batch_execution": {
"strategy": "work-pool-docker",
"work_pool_name": "docpipe-docker-pool",
"image": "docling-pipelines:v1.0.0",
"image_pull_policy": "IfNotPresent",
"networks": ["docpipe-network"],
"env": {
"PYTHONPATH": "/app/src",
"LOG_LEVEL": "INFO",
"OLLAMA_HOST": "http://ollama:11434",
"OPENSEARCH_HOST": "opensearch",
"OPENSEARCH_PORT": "9200",
"OPENSEARCH_USERNAME": "admin",
"OPENSEARCH_PASSWORD": "<your-opensearch-password>",
"OPENSEARCH_USE_SSL": "false",
"OPENSEARCH_VERIFY_CERTS": "false",
"PREFECT_API_URL": "http://prefect-server:4200/api",
"PREFECT_MODE": "server"
},
"batch_storage": {
"type": "local",
"path": "/data/batches"
}
}
}
}
Requirements:
local type)Job stats store guidance:
JsonJobStatsStore for Docker work pools unless submitter and all worker containers share the same mounted filesystem path for job statsprocess execution on a shared volume, set DOCPIPE_JOB_STATS_BASE_DIR to the mounted absolute path seen inside that runtime, for example /app/data/job_statsPostgresJobStatsStoreBatch storage determines how PyArrow table data is transferred between submitter and workers.
| Type | Use Case | Size Limit | Network Required | Shared Storage |
|---|---|---|---|---|
inline |
Small batches, testing | ~512KB | No | No |
local |
Docker Compose, same machine, shared volumes | Unlimited | No | Yes (filesystem) |
Description: Serializes batch data as JSON in Prefect parameters.
Configuration:
{
"batch_storage": {
"type": "inline"
}
}
Limitations:
PREFECT_SERVER_API_MAX_PARAMETER_SIZE)Overriding size limits:
Set on Prefect Server (not workers or submitter):
# Increase to 2MB
export PREFECT_SERVER_API_MAX_PARAMETER_SIZE=2097152
# Restart Prefect Server
Use cases:
Description: Writes batch data to shared filesystem.
Configuration:
{
"batch_storage": {
"type": "local",
"path": "/data/batches"
}
}
Requirements:
Use cases:
Example Docker Compose volume:
services:
docpipe-submitter:
volumes:
- batch-data:/data/batches
docpipe-worker:
volumes:
- batch-data:/data/batches
volumes:
batch-data:
"bucket": "docpipe-batches",
"prefix": "tmp/batches/",
"access_key": "minioadmin",
"secret_key": "minioadmin", <!-- pragma: allowlist secret -->
"endpoint_url": "http://minio:9000" } } ```
{
"name": "docker-compose-pipeline",
"flow_id": "docker-example-001",
"description": "Pipeline using Docker work pool with local storage",
"storage": "in-memory",
"execute_type": "local",
"global_config": {
"doc_column": "content",
"prefect": {
"batch_execution": {
"strategy": "work-pool-docker",
"work_pool_name": "docpipe-docker-pool",
"image": "docling-pipelines:latest",
"image_pull_policy": "Never",
"networks": ["docpipe-network"],
"env": {
"PYTHONPATH": "/app/src",
"LOG_LEVEL": "INFO",
"OLLAMA_HOST": "http://ollama:11434",
"OPENSEARCH_HOST": "opensearch",
"OPENSEARCH_PORT": "9200",
"OPENSEARCH_USERNAME": "admin",
"OPENSEARCH_PASSWORD": "<your-opensearch-password>",
"OPENSEARCH_USE_SSL": "false",
"OPENSEARCH_VERIFY_CERTS": "false",
"PREFECT_API_URL": "http://prefect-server:4200/api",
"PREFECT_MODE": "server"
},
"batch_storage": {
"type": "local",
"path": "/data/batches"
}
}
}
},
"flow": [
{
"name": "ingest_documents",
"type": "ingest_source",
"config": {
"provider": "filesystem",
"connection_params": {"paths": ["/data/input"]},
"include_filter": "pdf,txt,docx"
}
},
{
"name": "extract_content",
"type": "extract_operator",
"depends_on": ["ingest_documents"],
"config": {
"text_extraction": {
"provider": "docling_serve",
"provider_config": {
"base_url": "http://docling:5000"
}
},
"entity_extraction": {"provider": "none"}
}
}
]
}
Docker-based distributed execution uses docker/docker-compose.distributed.yml to run:
Core Services (Required):
Optional Services:
OLLAMA_HOST pointing to existing instanceDOCLING_SERVE_URL pointing to existing instanceOPENSEARCH_HOST pointing to existing instanceNote: The optional services are included for convenience in local/POC setups. In production:
┌─────────────────┐
│ Your Machine │
│ (Submitter) │──┐
└─────────────────┘ │
│ Submit Flow
↓
┌──────────────────────────────────────┐
│ Prefect Server │
│ (Central Coordinator) │
└──────────────────────────────────────┘
│
┌────────────┼────────────┐
↓ ↓ ↓
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Worker 1 │ │ Worker 2 │ │ Worker 3 │
│ (Docker) │ │ (Docker) │ │ (Docker) │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
└────────────┼────────────┘
↓
┌─────────────┐
│ MinIO │
│ (S3 Storage)│
└─────────────┘
1. Build the Docling Pipelines Image
# From project root
docker build -t docling-pipelines:latest .
Or with Podman:
podman build -t docling-pipelines:latest .
2. Start the Distributed Stack
# Start all services
docker-compose -f docker/docker-compose.distributed.yml up -d
Or with Podman:
podman-compose -f docker/docker-compose.distributed.yml up -d
This starts:
prefect-postgres: Database for Prefect serverprefect-server: Prefect orchestration serverprefect-worker: 4 worker replicasminio: S3-compatible storageollama: LLM service with modelsdocling-serve: Document processingopensearch: Vector databaseopensearch-dashboards: OpenSearch UI3. Verify Services
# Check containers
docker-compose -f docker/docker-compose.distributed.yml ps
# Check Prefect server
curl http://localhost:4200/api/health
# Check MinIO
curl http://localhost:9000/minio/health/live
# Check Ollama
curl http://localhost:11434/api/tags
4. Create Work Pool
Workers automatically create the work pool on startup. Verify:
export PREFECT_API_URL=http://localhost:4200/api
prefect work-pool ls
5. Set Environment Variables
export PREFECT_MODE=server
export PREFECT_API_URL=http://localhost:4200/api
Critical: Without PREFECT_MODE=server, Docling Pipelines uses ephemeral mode and ignores work pool configuration.
6. Configure Flow
See Example 1: Docker Work Pool with Local Storage above.
7. Run Flow
# Place documents in data/input
mkdir -p data/input
cp your-documents/* data/input/
# Run flow
docling-pipelines --flow-file your-flow.json
8. Monitor Execution
Shared Storage:
Batch data must be accessible to both the submitter and all workers. The compose file uses shared volumes for:
volumes:
- ./data:/app/data # Shared data directory
- ./logs:/app/logs # Shared logs directory
Docker Network:
All services must be on the same network (docpipe-net).
Scaling Workers:
# Scale to 8 workers
docker-compose -f docker/docker-compose.distributed.yml up -d --scale prefect-worker=8
# Stop services
docker-compose -f docker/docker-compose.distributed.yml down
# Stop and remove volumes (WARNING: deletes data)
docker-compose -f docker/docker-compose.distributed.yml down -v
Symptom: Work pool configuration ignored, jobs run locally
Cause: PREFECT_MODE not set to server
Solution:
export PREFECT_MODE=server
export PREFECT_API_URL=http://your-prefect-server:4200/api
Verification:
echo $PREFECT_MODE # Should output: server
echo $PREFECT_API_URL
Symptom: Flow runs stay in “Scheduled” state
Solutions:
# Verify work pool exists
prefect work-pool ls
# Check worker is connected
prefect worker ls
# Verify work pool name matches flow JSON
For local storage:
# Ensure path exists and is writable
mkdir -p /data/batches
chmod 777 /data/batches
Docker:
# Verify services on same network
docker network inspect docpipe-net
# Test connectivity
docker-compose exec prefect-worker ping -c 1 ollama
Error:
ValueError: work_pool_name is required for WorkPool strategy
Solution: Add work_pool_name to configuration:
{
"prefect": {
"batch_execution": {
"work_pool_name": "docpipe-pool"
}
}
}
Error:
WorkPoolNotFound: Work pool 'docpipe-pool' not found
Solution: Create the work pool:
# For process work pool
prefect work-pool create docpipe-pool --type process
# For Docker work pool
prefect work-pool create docpipe-pool --type docker
Error:
ValueError: batch_storage.path is required when batch_storage.type is 'local'
Solution: Add required configuration:
{
"batch_storage": {
"type": "local",
"path": "/data/batches"
}
}
Error:
ValueError: S3 credentials are required when batch_storage.type is 's3'
Solution: Provide credentials:
{
"batch_storage": {
"type": "s3",
"bucket": "my-bucket",
"access_key": "your-access-key-id",
"secret_key": "<your-secret-access-key>" <!-- pragma: allowlist secret -->
}
}
Error:
Could not connect to Prefect Server at http://localhost:4200
Solution: Ensure Prefect Server is running:
# Check server health
curl http://localhost:4200/api/health
# Start server (Docker Compose)
docker-compose up -d prefect-server
# Or start locally
prefect server start
prefect work-pool ls
prefect deployment ls
Look for docpipe-batch-subflow/<your-deployment-name>.
# Start worker (separate terminal)
prefect worker start --pool docpipe-pool
Worker should show “Worker started” message.
For local:
ls -la /data/batches
Symptoms: Batches take longer than expected
Possible causes:
Solutions:
Symptoms: Flow runs stay in “Scheduled” state
Possible causes:
Solutions:
# Check workers running
prefect worker ls
# Start worker
prefect worker start --pool docpipe-pool
# Check work pool configuration
prefect work-pool inspect docpipe-pool
Enable debug logging for detailed troubleshooting:
DS_LOG_LEVEL=DEBUG docling-pipelines --flow-file your-flow.json
Flow JSON:
{
"global_config": {
"doc_column": "content"
}
}
Environment:
# PREFECT_MODE=ephemeral (or not set - this is default)
When to use:
Flow JSON:
{
"global_config": {
"prefect": {
"batch_execution": {
"strategy": "work-pool-process",
"work_pool_name": "docpipe-pool",
"batch_storage": {
"type": "local",
"path": "/tmp/docpipe-batches"
}
}
}
}
}
Environment:
export PREFECT_MODE=server
export PREFECT_API_URL=http://localhost:4200/api
When to use:
Flow JSON:
{
"global_config": {
"prefect": {
"batch_execution": {
"strategy": "work-pool-docker",
"work_pool_name": "docpipe-pool",
"image": "docling-pipelines:latest",
"env": {
"PREFECT_MODE": "server",
"PREFECT_API_URL": "http://prefect-server:4200/api"
},
"batch_storage": {
"type": "s3",
"bucket": "docpipe-batches",
"endpoint_url": "http://minio:9000"
}
}
}
}
}
Environment (submitter):
export PREFECT_MODE=server
export PREFECT_API_URL=http://localhost:4200/api
When to use:
| Feature | Ephemeral | Local Distributed | Docker |
|---|---|---|---|
| Setup Complexity | ⭐ Simple | ⭐⭐ Medium | ⭐⭐⭐ Complex |
| Scalability | ❌ Single machine | ✅ Single machine | ✅✅ Multi-container |
| Isolation | ❌ None | ❌ Process-level | ✅ Container |
| Resource Limits | ❌ No | ❌ No | ✅ Yes |
| Production Ready | ❌ No | ❌ No | ✅ Yes |
| Fault Tolerance | ❌ No | ✅ Basic | ✅✅ Good |
From Ephemeral to Local Distributed:
PREFECT_MODE=serverFrom Local Distributed to Docker:
| Variable | Required | Description | Example |
|---|---|---|---|
PREFECT_MODE |
Yes (for distributed) | Execution mode | server or ephemeral |
PREFECT_API_URL |
Yes (for distributed) | Prefect server URL | http://localhost:4200/api |
DOCPIPE_STORAGE_BACKEND |
Optional | Effective job stats storage backend for worker runtime; inherited from submitter if omitted | filesystem, postgresql, inmemory |
DOCPIPE_FRAMEWORK_TYPE |
Optional | Effective job framework type for worker runtime; inherited from submitter if omitted | default |
DOCPIPE_JOB_STATS_BASE_DIR |
Optional for filesystem store | Absolute shared job stats path for filesystem-backed job stats; inherited from submitter if omitted | /app/data/job_stats |
DOCPIPE_POSTGRES_HOST |
Optional for PostgreSQL store | PostgreSQL host for job stats store; inherited from submitter if omitted | postgres |
DOCPIPE_POSTGRES_PORT |
Optional for PostgreSQL store | PostgreSQL port for job stats store; inherited from submitter if omitted | 5432 |
DOCPIPE_POSTGRES_DB |
Optional for PostgreSQL store | PostgreSQL database name for job stats store; inherited from submitter if omitted | docpipe |
DOCPIPE_POSTGRES_USER |
Optional for PostgreSQL store | PostgreSQL user for job stats store; inherited from submitter if omitted | docpipe_user |
DOCPIPE_POSTGRES_PASSWORD |
Required for PostgreSQL store unless supplied in config | PostgreSQL password for job stats store | secret |
OLLAMA_HOST |
For Ollama operators | Ollama server URL | http://ollama:11434 |
OPENSEARCH_HOST |
For OpenSearch | OpenSearch host | localhost |
OPENSEARCH_PORT |
For OpenSearch | OpenSearch port | 9200 |
OPENSEARCH_USERNAME |
For OpenSearch | Username | admin |
OPENSEARCH_PASSWORD |
For OpenSearch | Password | <your-opensearch-password> |
OPENSEARCH_USE_SSL |
For OpenSearch | Use SSL | false |
OPENSEARCH_VERIFY_CERTS |
For OpenSearch | Verify certificates | false |
Notes:
batch_storage section.Note: The deployment_name field is optional and defaults to "docpipe-batch-subflow". You only need to specify it if you want to create multiple deployments of the same flow in the same work pool (advanced use case).
Minimal configuration:
{
"global_config": {
"prefect": {
"batch_execution": {
"strategy": "work-pool-process",
"work_pool_name": "docpipe-pool",
"batch_storage": {
"type": "local",
"path": "/tmp/batches"
}
}
}
}
}
Inline storage (for small batches):
{
"global_config": {
"prefect": {
"batch_execution": {
"strategy": "work-pool-docker",
"work_pool_name": "docpipe-docker-pool",
"batch_storage": {
"type": "inline"
}
}
}
}
}
Note: Inline storage passes batch data directly through Prefect’s API. Only suitable for small batches due to
PREFECT_SERVER_API_MAX_PARAMETER_SIZElimitations. For production workloads with larger batches, uselocalors3storage.
sample_flows/quickstart/complete_pipeline_ollama.jsondocker/docker-compose.distributed.yml
USER_GUIDE_PIPELINE_SETUP.mdThe following features are planned for future releases to enhance distributed execution capabilities:
Current State: Job statistics are stored locally using pickle files, which limits visibility in distributed environments where multiple workers operate independently.
Planned Enhancement: Add pluggable storage backends for job statistics, enabling distributed workers to share job metrics in a common database.
Supported Backends (planned):
Benefits:
Current State: Incremental metadata tables (tracking processed files, checksums, etc.) are stored locally, preventing workers from sharing state about which data has been processed.
Planned Enhancement: Add external storage support for incremental metadata, allowing all workers to access and update shared incremental processing state.
Supported Backends (planned):
Benefits:
Use Cases:
Use descriptive names indicating environment and type:
docpipe-dev-docker - Development Docker pooldocpipe-prod-process - Production process pooldocpipe-staging-process - Staging process poolDocker:
--cpus and --memory flags when starting workersdocker statsError:
ValueError: batch_storage.path is required when batch_storage.type is 'local'
Solution: Add required configuration:
{
"batch_storage": {
"type": "local",
"path": "/data/batches"
}
}
"bucket": "my-bucket",
"access_key": "your-access-key-id",
"secret_key": "<your-secret-access-key>" } } ```
Error:
Could not connect to Prefect Server at http://localhost:4200
Solution: Ensure Prefect Server is running:
# Check server health
curl http://localhost:4200/api/health
# Start server (Docker Compose)
docker-compose up -d prefect-server
# Or start locally
prefect server start
prefect work-pool ls
prefect deployment ls
Look for docpipe-batch-subflow/<your-deployment-name>.
# Start worker (separate terminal)
prefect worker start --pool docpipe-pool
Worker should show “Worker started” message.
ls -la /data/batches
Symptoms: Batches take longer than expected
Possible causes:
Solutions:
Symptoms: Flow runs stay in “Scheduled” state
Possible causes:
Solutions:
# Check workers running
prefect worker ls
# Start worker
prefect worker start --pool docpipe-pool
# Check work pool configuration
prefect work-pool inspect docpipe-pool
Enable debug logging for detailed troubleshooting:
DS_LOG_LEVEL=DEBUG docling-pipelines --flow-file your-flow.json
Flow JSON:
{
"global_config": {
"doc_column": "content"
}
}
Environment:
# PREFECT_MODE=ephemeral (or not set - this is default)
When to use:
Flow JSON:
{
"global_config": {
"prefect": {
"batch_execution": {
"strategy": "work-pool-process",
"work_pool_name": "docpipe-pool",
"batch_storage": {
"type": "local",
"path": "/tmp/docpipe-batches"
}
}
}
}
}
Environment:
export PREFECT_MODE=server
export PREFECT_API_URL=http://localhost:4200/api
When to use:
Flow JSON:
{
"global_config": {
"prefect": {
"batch_execution": {
"strategy": "work-pool-docker",
"work_pool_name": "docpipe-pool",
"image": "docling-pipelines:latest",
"env": {
"PREFECT_MODE": "server",
"PREFECT_API_URL": "http://prefect-server:4200/api"
},
"batch_storage": {
"type": "s3",
"bucket": "docpipe-batches",
"endpoint_url": "http://minio:9000"
}
}
}
}
}
Environment (submitter):
export PREFECT_MODE=server
export PREFECT_API_URL=http://localhost:4200/api
When to use:
| Feature | Ephemeral | Local Distributed | Docker |
|---|---|---|---|
| Setup Complexity | ⭐ Simple | ⭐⭐ Medium | ⭐⭐⭐ Complex |
| Scalability | ❌ Single machine | ✅ Single machine | ✅✅ Multi-container |
| Isolation | ❌ None | ❌ Process-level | ✅ Container |
| Resource Limits | ❌ No | ❌ No | ✅ Yes |
| Production Ready | ❌ No | ❌ No | ✅ Yes |
| Fault Tolerance | ❌ No | ✅ Basic | ✅✅ Good |
From Ephemeral to Local Distributed:
PREFECT_MODE=serverFrom Local Distributed to Docker:
| Variable | Required | Description | Example |
|---|---|---|---|
PREFECT_MODE |
Yes (for distributed) | Execution mode | server or ephemeral |
PREFECT_API_URL |
Yes (for distributed) | Prefect server URL | http://localhost:4200/api |
OLLAMA_HOST |
For Ollama operators | Ollama server URL | http://ollama:11434 |
OPENSEARCH_HOST |
For OpenSearch | OpenSearch host | localhost |
OPENSEARCH_PORT |
For OpenSearch | OpenSearch port | 9200 |
OPENSEARCH_USERNAME |
For OpenSearch | Username | admin |
OPENSEARCH_PASSWORD |
For OpenSearch | Password | <your-opensearch-password> |
OPENSEARCH_USE_SSL |
For OpenSearch | Use SSL | false |
OPENSEARCH_VERIFY_CERTS |
For OpenSearch | Verify certificates | false |
Note: Batch storage for distributed execution is configured in the flow JSON batch_storage section.
Minimal configuration:
{
"global_config": {
"prefect": {
"batch_execution": {
"strategy": "work-pool-process",
"work_pool_name": "docpipe-pool",
"batch_storage": {
"type": "local",
"path": "/tmp/batches"
}
}
}
}
}
sample_flows/quickstart/complete_pipeline_ollama.jsondocker/docker-compose.distributed.yml
Use descriptive names indicating environment and type:
docpipe-dev-docker - Development Docker pooldocpipe-prod-process - Production process pooldocpipe-staging-process - Staging process poolDocker:
--cpus and --memory flags when starting workersdocker stats| Scenario | Recommended Storage |
|---|---|
| Development/testing | inline (if batches <400KB) or local |
| Docker Compose | local with shared volumes |
| Production | s3 with proper IAM/credentials |
Monitor these metrics:
Distributed execution in Docling Pipelines enables horizontal scaling and improved throughput through Prefect work pools and workers. Key takeaways:
PREFECT_MODE=server for distributed executionFor additional help, consult:
USER_GUIDE_PIPELINE_SETUP.md - Complete setup guide