Skip to main content

Standalone (Single Node)

Run the entire DocAI Fabric platform on a single machine with one Docker Compose file. This is the simplest way to host the product yourself and is intended for demos, evaluations, and small workloads.

For production workloads that need redundancy and horizontal scale, use the High Availability (Multi-Node) model instead.

What you get

Everything runs on one host: the application, the workflow workers that process your documents, the built-in OCR engines, the web interface, and a Redis instance for the job queue. The only things that live outside the host are the language model endpoints you connect (your own GPU servers and/or cloud providers) and the licensing service.

┌───────────────────────────────────────────────────────────────┐
│ Your machine (VM or laptop) │
│ Docker + Docker Compose │
│ │
│ ┌──────────────────────┐ ┌──────────────┐ │
│ │ docaifabric │◄──────►│ redis │ │
│ │ app + workers │ │ job queue │ │
│ │ + OCR (Paddle/Tess) │ └──────────────┘ │
│ │ + web UI │ │
│ └──────────┬───────────┘ │
│ │ local volume: ./data/storage │
└───────────────┼───────────────────────────────────────────────┘
│ outbound HTTPS
├──► Your OpenAI-compatible language model endpoints (added in the UI)
└──► license.docaifabric.com (licensing & usage)

Key points:

  • OCR runs entirely on this host. The image bundles the PaddleOCR and Tesseract engines, so no cloud OCR service is required and no document images leave your machine for text recognition.
  • A default language model is set in your .env (any OpenAI-compatible endpoint). Additional models are added in the app on the Models page after setup. See Connecting Models for details.
  • All your data lives in one folder (./data/storage by default), which makes backup and restore a simple file copy.

Where it runs

You can run this on a dedicated virtual machine, a physical server, or even a laptop for a quick demo. The only requirement is a working Docker installation.

Operating system

The application ships as a Linux container for the x86_64 (amd64) architecture, but Docker lets you run it on any major operating system:

Operating systemSupportedNotes
Linux (x86_64)Yes (recommended)Native. Best choice for anything beyond a quick demo. Install Docker Engine and the Compose plugin.
Windows 10 / 11 (x86_64)YesInstall Docker Desktop with the WSL 2 backend. The Linux container runs natively.
macOS (Intel)YesInstall Docker Desktop. The container runs natively.
macOS (Apple Silicon: M1/M2/M3/M4)Yes, with one settingDocker Desktop runs the x86_64 image through emulation. Enable Settings > General > Use Rosetta for x86/amd64 emulation, and set RULE_EXECUTOR_USE_VM=true in your .env (see below). Fine for demos, slower than a native x86_64 host.

In short: any OS that can run Docker works. The only customization is for Apple Silicon Macs, which need the Rosetta emulation setting and one extra environment variable.

Sizing

ResourceMinimum (demo)Recommended
CPU4 cores4 or more cores
RAM8 GB8 GB or more
Disk20 GB free50 GB or more, depending on document volume

OCR is the most CPU-intensive part of the pipeline and runs on this host, so add CPU cores if you plan to process many documents at once.

Prerequisites

Before you start, make sure you have:

  1. Docker and Docker Compose. Docker Engine 20.10 or newer (Linux), or the latest Docker Desktop (Windows / macOS). Compose v2 is included with both.

  2. Outbound network access from the host for the image pull, licensing, and the language models you connect. The exact destinations, protocols, and ports are listed under Network and connectivity below.

  3. At least one OpenAI-compatible language model endpoint. The deployment needs one default LLM to start the processing pipeline, set via .env (Step 4). It can be an on-prem GPU server (Ollama, vLLM, ...), a cloud provider (OpenAI, Azure, Google, Anthropic, or compatible), or a combination. You can add more models in the app afterward on the Models page.

  4. Registry access from us. Before you can pull the image, request a registry username and access token for signing in to ghcr.io from deployment@docaifabric.com. The image reference itself is already set in the .env below (ghcr.io/docaifabric/docaifabric:latest).

    You generate your own ADMIN_API_KEY and TENANT_MODELS_ENCRYPTION_KEY later in this guide; those never come from us.

Network and connectivity

Every connection the application makes is outbound. The only inbound requirement is the port your users use to reach the web interface.

Outbound (from the host)

DestinationProtocol and portRequiredPurpose
license.docaifabric.comHTTPS (TCP 443)YesLicensing and usage reporting
ghcr.io (GitHub Container Registry)HTTPS (TCP 443)YesPull the application image and updates
Your on-prem model serversHTTP or HTTPS (TCP, the port you expose)If usedClassification and extraction on your own GPU servers
api.anthropic.comHTTPS (TCP 443)If usedAnthropic Claude models
api.openai.comHTTPS (TCP 443)If usedOpenAI models
Your Azure OpenAI / Google endpointsHTTPS (TCP 443)If usedModels hosted on those providers
Your SMTP relaySMTP (TCP 587 or 25, per your relay)If usedOutgoing email: invitations, password resets, notifications (see Enable email notifications)

Inbound (to the host)

PortProtocolPurpose
8080HTTPWeb interface and API. For anything beyond a local demo, put a reverse proxy in front to serve HTTPS.
note
  • On-prem model endpoints use whichever port you chose when you deployed the model server (for example, 8000 for vLLM or 11434 for Ollama). This traffic stays on your internal network. Plain HTTP is acceptable there because it never leaves your network; use HTTPS if your security policy requires it.
  • Cloud model providers are all reached over HTTPS on port 443. You only need to open the ones you actually connect.
  • Outbound proxy. If your network requires an outbound HTTP proxy, set the standard HTTP_PROXY, HTTPS_PROXY, and NO_PROXY variables in your .env file.

Setup: your part

Step 1: Install Docker

Follow the official instructions for your operating system:

  • Linux: install Docker Engine and the Compose plugin.
  • Windows / macOS: install Docker Desktop and start it.

Verify it works:

docker --version
docker compose version

Step 2: Create a working folder

Create one working folder for the deployment. It holds your Compose file, your .env settings file, and a data/storage subfolder where all application data is kept.

mkdir -p ~/docai/data/storage
cd ~/docai

This creates ~/docai (the working folder) with data/storage inside it, and moves you into ~/docai. Run the remaining commands from there.

Step 3: Add the Compose file

Save the following as docker-compose.yml in the working folder (~/docai). You can copy the block below or download docker-compose.yml:

services:
redis:
image: redis:7-alpine
command: redis-server --appendonly yes --maxmemory 512mb --maxmemory-policy noeviction
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
restart: unless-stopped

docaifabric:
image: ${DOCAI_IMAGE}
# The image is x86_64 (amd64) only. This line lets it run on Apple Silicon
# Macs under emulation; on a native x86_64 host it is a harmless no-op.
platform: linux/amd64
depends_on:
redis:
condition: service_healthy
ports:
- "8080:8080"
volumes:
- ./data/storage:/app/storage
environment:
# Connect to the Redis service defined below
- REDIS_URL=redis://redis:6379/0
# Secrets (set these in .env)
- ADMIN_API_KEY=${ADMIN_API_KEY}
- TENANT_MODELS_ENCRYPTION_KEY=${TENANT_MODELS_ENCRYPTION_KEY}
# Public URL used in links the app shows
- APP_URL=${APP_URL:-http://localhost:8080}
# OCR engines. The two bundled engines run locally, no cloud. Microsoft
# Read is optional and calls Azure Document Intelligence (needs the
# endpoint + key below and outbound HTTPS). Values come from .env (Step 4).
- RAPID_OCR_ENABLED=${RAPID_OCR_ENABLED:-true}
- TESSERACT_OCR_ENABLED=${TESSERACT_OCR_ENABLED:-true}
- MICROSOFT_OCR_ENABLED=${MICROSOFT_OCR_ENABLED:-false}
- MICROSOFT_OCR_ENDPOINT=${MICROSOFT_OCR_ENDPOINT:-}
- MICROSOFT_OCR_KEY=${MICROSOFT_OCR_KEY:-}
- DEFAULT_OCR_ENGINE=${DEFAULT_OCR_ENGINE:-rapid_ocr}
# Default LLM — any OpenAI-compatible endpoint. Values come from .env (Step 4).
- LLM_BASE_URL=${LLM_BASE_URL:-}
- LLM_MODEL=${LLM_MODEL:-}
- LLM_API_KEY=${LLM_API_KEY:-}
- LLM_PROTOCOL=${LLM_PROTOCOL:-openai_compatible}
- LLM_AUTH_MODE=${LLM_AUTH_MODE:-bearer}
# Advanced: several LLM endpoints (failover / load-balance) as a JSON array.
- AZURE_OPENAI_ENDPOINTS=${AZURE_OPENAI_ENDPOINTS:-}
# AI Assistant. By default it uses the Default LLM above and turns on
# automatically once a Default LLM is set. Set ASSISTANT_ENABLED=false to
# turn it off, or ASSISTANT_MODEL to give it a different model (Step 4).
- ASSISTANT_ENABLED=${ASSISTANT_ENABLED:-true}
- ASSISTANT_MODEL=${ASSISTANT_MODEL:-}
# Email notifications (optional). Set the SMTP_* values in .env to enable
# invitation and notification emails; email stays off while SMTP_HOST is empty.
- SMTP_HOST=${SMTP_HOST:-}
- SMTP_PORT=${SMTP_PORT:-587}
- SMTP_USER=${SMTP_USER:-}
- SMTP_PASSWORD=${SMTP_PASSWORD:-}
- SMTP_FROM=${SMTP_FROM:-}
- SMTP_USE_TLS=${SMTP_USE_TLS:-true}
# Apple Silicon Macs only (see .env). Harmless to leave as-is elsewhere.
- RULE_EXECUTOR_USE_VM=${RULE_EXECUTOR_USE_VM:-false}
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "python -c 'import requests; requests.get(\"http://localhost:8080/health\", timeout=5)'"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s

volumes:
redis_data:

The image ships with sensible defaults for storage (local filesystem at the mounted ./data/storage folder) and the workflow workers, so the Compose file only sets what is specific to your install. The remaining settings, including which OCR engines to run, go in your .env in the next step.

Step 4: Create your settings file

Save the following as .env in the working folder (~/docai), then fill in the values. You can copy the block below or download env.example and rename it to .env:

# Application image. :latest is the most recent release and is simplest for a
# demo. For a long-lived or production install, pin the exact version tag we
# give you at onboarding (e.g. ...:2026.06.25-2) so you can roll back to a known
# version. Check what you are running any time with GET /api/version.
DOCAI_IMAGE=ghcr.io/docaifabric/docaifabric:latest

# Admin key for management operations. Generate a random value:
# openssl rand -hex 32
ADMIN_API_KEY=

# Encrypts the language model API keys you enter in the app.
# Generate ONCE and never change it (see warning below):
# openssl rand -base64 32
TENANT_MODELS_ENCRYPTION_KEY=

# The URL users will use to reach the app. For a laptop demo, leave the default.
APP_URL=http://localhost:8080

# OCR engines (run locally, no cloud). Keep at least one enabled.
RAPID_OCR_ENABLED=true
TESSERACT_OCR_ENABLED=true
# Optional: Microsoft Read (Azure Document Intelligence). Calls Azure, so the
# container needs outbound HTTPS to the endpoint below. Leave disabled to stay
# fully local. To use it, set all three:
# MICROSOFT_OCR_ENABLED=true
# MICROSOFT_OCR_ENDPOINT=https://<your-resource>.cognitiveservices.azure.com/
# MICROSOFT_OCR_KEY=<your-key>
# Default engine for new projects (must be one you enabled above).
DEFAULT_OCR_ENGINE=rapid_ocr

# Default LLM — any OpenAI-compatible endpoint (Ollama, vLLM, a cloud key, ...).
# IMPORTANT: this URL must be reachable from INSIDE the container. A bare name
# like http://ollama:11434 only works if "ollama" is a service in THIS Compose
# file (it is not, by default). See "Default LLM" below for the right address.
# Example below: Ollama running on the same machine, reached via host.docker.internal.
LLM_BASE_URL=http://host.docker.internal:11434
LLM_MODEL=gemma4
LLM_API_KEY= # leave blank for Ollama; set the key for cloud providers

# AI Assistant (optional). It uses the Default LLM above unless you set a
# different model here. Set ASSISTANT_ENABLED=false to turn the assistant off.
# ASSISTANT_MODEL=
# ASSISTANT_ENABLED=true

# Email notifications (optional). Set SMTP_HOST to enable invitation and
# notification emails; leave it unset to keep email off. See "Enable email
# notifications" in this guide for examples and details.
# SMTP_HOST=
# SMTP_PORT=587
# SMTP_USER=
# SMTP_PASSWORD=
# SMTP_FROM=
# SMTP_USE_TLS=true

# Apple Silicon Macs only:
# RULE_EXECUTOR_USE_VM=true
Keep your encryption key safe and stable

TENANT_MODELS_ENCRYPTION_KEY encrypts the model API keys you save in the application. Generate it once, store a copy somewhere safe, and never change it. If it is lost or changed, the saved model keys can no longer be decrypted and must be re-entered. Back up this file together with your data (see Backup and restore).

OCR engines. Both bundled engines run locally on this host, no cloud: PaddleOCR (RAPID_OCR_ENABLED) and Tesseract (TESSERACT_OCR_ENABLED). Keep at least one true, or the workflow will report that no OCR engine is available. DEFAULT_OCR_ENGINE picks which one new projects use by default. Tesseract is the more robust choice under emulation (for example on an Apple Silicon Mac). Microsoft Read is optional and not local: set MICROSOFT_OCR_ENABLED=true plus MICROSOFT_OCR_ENDPOINT and MICROSOFT_OCR_KEY to use Azure Document Intelligence (the container then needs outbound HTTPS to that endpoint), and set DEFAULT_OCR_ENGINE=microsoft_read to make it the default.

Default LLM. The deployment needs at least one language model to start the processing pipeline. Point it at any OpenAI-compatible endpoint with the three LLM_* variables. LLM_MODEL must match the model name the server actually serves (check with ollama list for Ollama).

LLM_BASE_URL must be reachable from inside the container

The application runs in a container, so LLM_BASE_URL is resolved from the container's network, not your shell. A short hostname like http://ollama:11434 only works if ollama is a service in this Compose file (it is not, by default) — otherwise you get Name or service not known and the model's circuit trips. Use the address that matches where your LLM runs:

Where the LLM runsLLM_BASE_URL
Same machine, Docker Desktop (macOS / Windows)http://host.docker.internal:11434
Same machine, Linux Docker enginehttp://host.docker.internal:11434 and add extra_hosts: ["host.docker.internal:host-gateway"] under the docaifabric service — or use the host's LAN IP
Another server (e.g. a GPU box)http://<that-host-ip-or-name>:11434

Also start Ollama with OLLAMA_HOST=0.0.0.0 so it accepts connections from the container, not just localhost. Verify reachability from inside the container:

docker compose exec docaifabric python -c "import httpx,os; u=os.environ['LLM_BASE_URL']; print(httpx.get(u.rstrip('/')+'/api/tags', timeout=10).status_code)"
  • On-prem (Ollama / vLLM, etc.): set LLM_BASE_URL per the table above, LLM_MODEL=gemma3, leave LLM_API_KEY blank. http:// is fine for endpoints on your own network.
  • Cloud (OpenAI and compatible): LLM_BASE_URL=https://api.openai.com, LLM_MODEL=gpt-4o-mini, LLM_API_KEY=sk-....

This is the deployment default. Once running, you (and tenant admins) can add more models, including your DGX servers and cloud providers, on the Models page. To configure several default endpoints for failover or load-balancing, omit the LLM_* vars and set AZURE_OPENAI_ENDPOINTS to a JSON array instead.

AI Assistant. The in-app assistant uses the same Default LLM by default, so you do not have to configure a second model. It turns on automatically once a Default LLM is set. Two optional knobs:

  • To run the assistant on a different model than the pipeline (for example a larger model for chat), set ASSISTANT_MODEL in .env to that model's name. It must be a model your deployment can reach: either the Default LLM, one of the endpoints in AZURE_OPENAI_ENDPOINTS, or a model you add on the Models page.
  • To turn the assistant off, set ASSISTANT_ENABLED=false.

A tenant admin can also override the assistant model per tenant on the Models page (Defaults tab), which takes precedence over ASSISTANT_MODEL.

Other optional settings

For throughput tuning, add NUM_WORKFLOW_WORKERS, MAX_PARALLEL_OCR, or MAX_PARALLEL_LLM under the docaifabric service's environment: in the Compose file. Set LOG_LEVEL=DEBUG there for more detailed logs.

Step 5: Sign in to the image registry and start

# Sign in once. We provide the username and access token during onboarding.
docker login ghcr.io

# Start the stack
docker compose up -d

The first start downloads the image and may take a few minutes. Check that it is healthy:

docker compose ps
curl http://localhost:8080/health

Step 6: First sign-in and admin user

Open the application in a browser:

http://localhost:8080

Follow the on-screen prompts to create your first administrator account. (Full first-run guidance is in Quick Start.)

Step 7: Connect your language models

OCR already works with the bundled local engines, so the only thing left is to connect a language model for classification and extraction.

  1. Open the Models page in the application.
  2. Add each endpoint:
    • Your own GPU server: choose the OpenAI-compatible option and enter its URL and key.
    • Cloud provider (optional): add your Anthropic or OpenAI key.
  3. Set which model to use for each task (classification, extraction, and so on).

Full instructions, including testing an endpoint, are in Connecting Models. You can connect several endpoints and the app will balance and fail over across them.

You are now ready to create a project and process documents.

Optional: use Microsoft Read OCR

The standalone setup runs the two bundled engines (PaddleOCR and Tesseract) entirely on this host. If you have an Azure Document Intelligence resource, you can use Microsoft Read instead of, or alongside, the local engines. Read often gives higher accuracy on dense or low-quality scans.

Microsoft Read is not local

Unlike the bundled engines, Microsoft Read sends page images to Azure. The container needs outbound HTTPS to your Document Intelligence endpoint, and pages leave the host. Keep using the bundled engines if you need to stay fully on-premises.

What you need: an Azure Document Intelligence (Cognitive Services) resource. From the Azure portal, under Keys and Endpoint, copy the Endpoint URL (looks like https://<your-resource>.cognitiveservices.azure.com/) and one Key.

Step 1: confirm the Compose file passes the variables through. Microsoft Read is off by default, so the three variables must be wired from .env into the container. In your docker-compose.yml, the docaifabric service's environment: block should contain:

      - MICROSOFT_OCR_ENABLED=${MICROSOFT_OCR_ENABLED:-false}
- MICROSOFT_OCR_ENDPOINT=${MICROSOFT_OCR_ENDPOINT:-}
- MICROSOFT_OCR_KEY=${MICROSOFT_OCR_KEY:-}

If your file instead has a hardcoded MICROSOFT_OCR_ENABLED=false (older template), replace it with the three lines above. A hardcoded value in environment: overrides whatever you put in .env, so Read can never turn on otherwise.

Step 2: set the three variables in .env:

MICROSOFT_OCR_ENABLED=true
MICROSOFT_OCR_ENDPOINT=https://<your-resource>.cognitiveservices.azure.com/
MICROSOFT_OCR_KEY=<your-key>

Keep RAPID_OCR_ENABLED and TESSERACT_OCR_ENABLED as they are if you want the local engines available as alternatives; you do not have to disable them.

Step 3: make Read the default for new projects (optional):

DEFAULT_OCR_ENGINE=microsoft_read

Leave DEFAULT_OCR_ENGINE as rapid_ocr (or tesseract) if you only want Read available as a per-project choice rather than the default.

Step 4: restart and verify:

docker compose up -d
docker compose logs docaifabric | grep -i ocr

You should see lines like:

✅ OCR pool: single endpoint 'ocr-default' from MICROSOFT_OCR_ENDPOINT (key_source=MICROSOFT_OCR_KEY)
✅ Initialized Microsoft OCR service

Microsoft Read will now appear as a selectable engine in each project's OCR step (and as the system default if you set DEFAULT_OCR_ENGINE=microsoft_read).

Read not showing up?

If the log shows the enabled engines as only ['rapid_ocr', 'tesseract'] and there are no OCR pool lines, the container is not seeing MICROSOFT_OCR_ENABLED=true. The usual causes are a hardcoded MICROSOFT_OCR_ENABLED=false in the Compose environment: block (see Step 1), an inline comment on the value (...=true # note is read literally, comment included), or a stale container, which you can recreate with docker compose up -d --force-recreate. Confirm what the container actually sees with docker exec docaifabric printenv | grep -i ocr.

Optional: enable email notifications

DocAI Fabric can send transactional emails through any SMTP relay you provide: team invitations, "you've been added to a workspace" notices, self-service password reset links, license notifications, and budget alerts. Email is off by default, and the application works fully without it. Invitations are still created (an admin shares the invitation link manually), but self-service password reset is only available with email enabled.

This section covers the install-time method: set the values in .env while you are already configuring the container. You can also configure and test SMTP live after the deployment is running, without editing files or restarting, using the CLI. See Configure SMTP (CLI); its built-in test-email command is the easiest way to confirm delivery. The two methods work together: the SMTP_* env vars below are the seed default, and any value you later set with the CLI takes precedence over them.

The Compose file from Step 3 already passes the SMTP_* variables into the container, so enabling email is just a matter of setting them in .env. Two typical setups:

# A) Authenticated relay with STARTTLS (a mail provider, Microsoft 365, Exchange):
SMTP_HOST=mail.example.com
SMTP_PORT=587
SMTP_USER=docai@example.com
SMTP_PASSWORD=<password or app password>
SMTP_FROM=docai@example.com

# B) Anonymous internal relay on port 25 (the relay allows your host by source IP):
SMTP_HOST=relay.example.internal
SMTP_PORT=25
SMTP_USE_TLS=false
SMTP_FROM=docai-fabric@example.com

Apply the change and send a test email:

docker compose up -d
# Invite a user from the Team page, then check the log:
docker compose logs docaifabric | grep -i "email sent"

Notes:

  • Connection security. SMTP_USE_TLS=true (the default) uses STARTTLS, the standard for port 587. For a plain-text relay on port 25, set SMTP_USE_TLS=false. Implicit TLS (usually port 465) is not supported; use a STARTTLS port instead.
  • Authentication is optional. If SMTP_USER and SMTP_PASSWORD are both empty, the application sends without logging in. This suits internal relays that allow clients by source IP.
  • SMTP_FROM defaults to SMTP_USER. With an anonymous relay there is no user, so set SMTP_FROM explicitly or the relay will reject the mail.
  • APP_URL appears inside the emails. The action links (accept an invitation, reset a password) and the logo image point at APP_URL, so it must be an address your recipients can reach. With the default http://localhost:8080, links in the emails will not work for anyone but you.
  • The container needs outbound access to the SMTP host and port; see Network and connectivity.

Backup and restore

Because everything is stored in one folder, backup is a file copy. The folder contains your documents, projects, transactions, model configuration, and the deployment's licensing identity.

Back up

  1. Stop the stack so files are in a consistent state:
    docker compose stop
  2. Copy the data folder and your settings file to a safe location:
    tar czf docai-backup-$(date +%Y%m%d).tgz data .env
    On a virtual machine you can instead take a VM snapshot while the stack is stopped.
  3. Start the stack again:
    docker compose start
tip

Always include the .env file in your backup. Without TENANT_MODELS_ENCRYPTION_KEY, restored model keys cannot be decrypted.

Restore

  1. Install Docker and place docker-compose.yml, .env, and the restored data folder in the same working folder.
  2. Start the stack:
    docker compose up -d

Your projects, documents, and configuration come back exactly as they were at backup time.

Getting updates

We publish new application image versions over time. Updating is a pull and restart; your data is never touched because it lives in the mounted folder, not in the image.

If DOCAI_IMAGE ends in :latest, updating is just:

docker compose pull        # fetch the newest release
docker compose up -d # recreate on the new image
docker image prune -f # optional: remove the old image

We also notify you by email (the address that requested onboarding) when a new version ships, and you can follow the What's New / changelog to track releases. To see what you are running, curl http://localhost:8080/api/version (for example {"version":"2026.06.25-2"}), which is handy when contacting support.

Pinning a version (recommended for production). To control exactly when you move and to be able to roll back, pin a specific tag instead of :latest. Find the newest version without changing your deployment, then set it in .env:

docker pull ghcr.io/docaifabric/docaifabric:latest
docker inspect ghcr.io/docaifabric/docaifabric:latest \
--format '{{range .Config.Env}}{{println .}}{{end}}' | grep APP_VERSION
# then set, e.g.: DOCAI_IMAGE=ghcr.io/docaifabric/docaifabric:2026.06.25-2
docker compose up -d

To roll back, set DOCAI_IMAGE to the previous version tag and run docker compose up -d again. (Rollback requires a specific tag, so production installs should pin rather than track :latest.)

Automated updates

For production, the High Availability model supports an automated update pipeline so you do not have to run these commands by hand. Ask us if you would like the same for a long-lived standalone install.

Accessing logs

All logs are available through Docker on the host.

# Follow the application logs live
docker compose logs -f docaifabric

# Last 200 lines
docker compose logs --tail=200 docaifabric

# Redis logs
docker compose logs -f redis

To increase detail, set LOG_LEVEL=DEBUG in .env and restart (docker compose up -d).

Sharing logs with support. Save the logs to a file and send it to us:

docker compose logs --no-color --tail=2000 docaifabric > docai-logs.txt

For querying by transaction, capping how much log Docker keeps on disk, and what to look for in a failure, see Application Logs (On-Premises).

Troubleshooting

SymptomLikely causeWhat to do
docker compose up cannot pull the imageNot signed in to the registryRun docker login ghcr.io with the username and token we provided
no matching manifest for linux/arm64 on pullApple Silicon Mac pulling the x86_64-only imageKeep platform: linux/amd64 on the docaifabric service (it is in the Compose file above), enable Rosetta in Docker Desktop, and set RULE_EXECUTOR_USE_VM=true
App container is unhealthy on first startStill downloading or initializingWait for start_period (about 40 seconds), then check docker compose ps again
"Model registry not initialized", or the workflow/Models page is emptyNo default LLM configured, so the pipeline did not startSet LLM_BASE_URL / LLM_MODEL in .env (or AZURE_OPENAI_ENDPOINTS), restart, and check the logs for "Model registry initialized" and "Started ... workflow worker(s)"
Classification or extraction failsThe default LLM is unreachable or the model name is wrongVerify LLM_BASE_URL is reachable from the container and LLM_MODEL matches a model the server serves; or add/select a model on the Models page
Model test shows "failed" in the UI even though the HTTP log says 200; processing keeps pausing; logs show Name or service not known and circuits OPEN (model_id=…)The LLM endpoint hostname is not resolvable/reachable from inside the container (for example LLM_BASE_URL=http://ollama:11434 with no ollama service)Set LLM_BASE_URL to an address the container can reach (host.docker.internal for a same-machine LLM, or the host's IP) per Default LLM, ensure the LLM listens on 0.0.0.0, then docker compose up -d (this also clears the tripped circuit)
"No OCR engine available"Both OCR engines disabled, or PaddleOCR failed to start (common under emulation)Confirm RAPID_OCR_ENABLED=true and TESSERACT_OCR_ENABLED=true, restart, and check docker compose logs docaifabric | grep -i ocr. Under emulation, Tesseract is the reliable engine
Saved model keys stopped working after a changeTENANT_MODELS_ENCRYPTION_KEY changedRestore the original key from your backup, or re-enter the model keys
Business rules misbehave on a MacApple Silicon emulationSet RULE_EXECUTOR_USE_VM=true in .env and restart

Next steps