How the ODS Installer Orchestrates the Installation Process: A 13-Phase Bash Pipeline

The ODS installer orchestrates the installation process through a deterministic Bash pipeline centered on install-core.sh, which sequences 13 discrete phases—from pre-flight validation to health checks—while using strict error handling (set -euo pipefail) and atomic locking to prevent concurrent model modifications.

The Osmantic/ODS repository delivers a containerized data stack deployment system designed for diverse hardware targets. Understanding how the ODS installer orchestrates the installation process reveals a modular architecture that isolates pure helper functions from stateful installation logic, enabling reliable deployments across NVIDIA, AMD, and Apple Silicon environments.

The Orchestrator Entry Point and Safety Foundations

The entire installation lifecycle is driven by ods/install-core.sh, which serves as the single entry point and central orchestrator. Before executing any phase-specific logic, the script establishes rigorous safety mechanisms to ensure predictable failure behavior.

At lines 17–38, the installer configures Bash for strict error handling:

set -euo pipefail

This setting causes the script to exit immediately on errors, treat unset variables as fatal, and propagate pipeline failures. The orchestrator also initializes a global INSTALL_PHASE variable to track execution context and registers a cleanup_on_error trap that reports the specific phase name when failures occur. A defensive SIGINT handler prevents accidental cancellation through "double-tap" confirmation.

Library Architecture: Pure Functions vs. Phase Scripts

The orchestrator maintains strict separation between stateless utilities and stateful installation steps. During initialization (lines 69–94), install-core.sh sources all files under installers/lib/, including:

These libraries contain pure functions with no side effects; they perform calculations and return data without modifying system state. The orchestrator only invokes them when needed, ensuring that side effects occur exclusively within the phase scripts located in installers/phases/.

The 13-Phase Installation Pipeline

The orchestrator progresses through thirteen distinct phases, setting INSTALL_PHASE before sourcing each corresponding script. This modular approach allows individual phases to fail with precise context while maintaining idempotency.

Phase 01 – Pre-flight Validation

installers/phases/01-preflight.sh performs system sanity checks before any installation work begins. This phase verifies the operating system compatibility, confirms required tools (curl, jq) are present, inspects optional tooling availability, validates firewall states, checks filesystem suitability, and detects existing installations that might conflict with the deployment.

Phase 02 – Hardware Detection and Tier Mapping

installers/phases/02-detection.sh executes hardware detection routines from installers/lib/detection.sh to determine GPU capabilities. Using tier-map.sh, the system calculates the appropriate hardware tier, which determines which machine learning models and container configurations will be selected for the deployment.

Phase 02b – External Service Integration

installers/phases/02b-external-services.sh prepares integrations with optional external LLM providers such as Lemonade or Ollama. This phase activates when flags like --external-llm-url are detected during argument parsing.

Phase 03 – Feature Selection

installers/phases/03-features.sh enables or disables optional services—including Voice, Workflows, and RAG (Retrieval-Augmented Generation)—based on environment variables populated during command-line argument processing.

Phase 04 – System Requirements

installers/phases/04-requirements.sh installs missing system packages using the distribution-specific package manager detected during pre-flight. This includes kernel headers, GPU drivers, and dependency libraries required by subsequent container operations.

Phase 05 – Docker Preparation

installers/phases/05-docker.sh ensures the Docker daemon is present and correctly configured. The phase pulls base compose files and configures daemon settings appropriate for the detected GPU type (NVIDIA, AMD, or Apple Silicon).

Phase 06 – Directory Structure and Permissions

installers/phases/06-directories.sh creates the $INSTALL_DIR directory tree and establishes strict permissions. The orchestrator generates environment files and immediately applies restrictive permissions (e.g., chmod 600 .env) to protect sensitive configuration data.

Phase 07 – Development Tools

installers/phases/07-devtools.sh installs optional debugging utilities such as git configuration helpers and enhanced jq tooling. These utilities support troubleshooting but are not required for runtime operation.

Phase 08 – Container Image Acquisition

installers/phases/08-images.sh pulls required container images for the LLM inference engine, dashboard, and any enabled optional services. The phase selects the appropriate GPU overlay file—docker-compose.amd.yml, docker-compose.nvidia.yml, or docker-compose.apple.yml—based on earlier detection results.

Phase 09 – Offline Mode Configuration

installers/phases/09-offline.sh disables network-dependent steps when the --offline flag is set. This configuration supports air-gapped deployments, particularly useful for Apple Silicon machines operating without internet connectivity.

Phase 10 – AMD GPU Optimization

installers/phases/10-amd-tuning.sh applies AMD-specific optimizations, including ROCm driver settings and memory allocation adjustments, when AMD GPUs are detected during the hardware discovery phase.

Phase 11 – Service Deployment

installers/phases/11-services.sh generates the final docker-compose.yml by merging the base configuration with GPU-specific overlays and enabled feature extensions. The orchestrator then executes docker compose up -d to launch the containerized stack.

Phase 12 – Health Verification

installers/phases/12-health.sh polls each container’s health endpoint to verify successful startup. The phase implements retry logic and reports detailed status information for each service before declaring the installation successful.

Phase 13 – Installation Summary

installers/phases/13-summary.sh prints URLs, access shortcuts, and post-installation instructions. This phase executes with set +e to ensure that cosmetic output failures never abort the installation after successful service deployment.

Concurrency Control and Error Handling

Before executing Phase 08 (image pulling), the orchestrator acquires a model lifecycle lock via ods_model_lifecycle_lock_acquire (lines 45–47). This atomic locking mechanism prevents concurrent installer instances from downloading models or modifying configurations simultaneously, protecting against corruption during parallel installations. The lock is released only after services are successfully brought online.

The combination of set -euo pipefail, the INSTALL_PHASE tracking variable, and the cleanup_on_error trap ensures that any failure immediately halts execution while reporting the exact phase where the error occurred, simplifying debugging and log analysis.

Command-Line Interface and Customization

The orchestrator parses flags in a while [[ $# -gt 0 ]] loop (lines 20–73), populating environment variables such as ENABLE_VOICE, ENABLE_RAG, and INSTALL_TIER that drive conditional logic throughout the phases.

Common invocation patterns include:


# Standard interactive installation

./install.sh

# Force tier 2 hardware profile with voice and RAG enabled, non-interactive mode

./install.sh --tier 2 --voice --rag --non-interactive

# Dry-run mode using existing Docker installation

./install.sh --skip-docker --dry-run

# Cloud deployment with external LLM provider

./install.sh --cloud --external-llm-url https://api.openai.com/v1 --external-llm-provider ollama

Summary

  • install-core.sh serves as the central orchestrator, implementing strict error handling with set -euo pipefail and phase-tracking via the INSTALL_PHASE variable.
  • The installation pipeline executes 13 discrete phases, from pre-flight validation (01-preflight.sh) through deployment (11-services.sh) to final health checks (12-health.sh).
  • Pure function libraries in installers/lib/ remain side-effect-free, while phase scripts in installers/phases/ handle all stateful system modifications.
  • Atomic locking via ods_model_lifecycle_lock_acquire prevents race conditions during model downloads and configuration changes.
  • GPU-specific logic uses tier mapping and overlay compose files to support NVIDIA, AMD, and Apple Silicon hardware targets through a unified interface.

Frequently Asked Questions

What is the entry point for the ODS installer?

The entry point is ods/install-core.sh, a Bash script that acts as the central orchestrator. It configures error handling, sources pure-function libraries from installers/lib/, parses command-line arguments, and sequentially executes the 13 installation phases located in installers/phases/.

How does the ODS installer handle hardware detection and GPU tiers?

During Phase 02, the orchestrator sources installers/phases/02-detection.sh, which calls hardware detection routines from installers/lib/detection.sh. The system uses tier-map.sh to calculate the appropriate hardware tier based on GPU capabilities, then selects corresponding Docker Compose overlays (docker-compose.nvidia.yml, docker-compose.amd.yml, or docker-compose.apple.yml) during Phase 08.

What safety mechanisms prevent installation failures or concurrent modifications?

The installer implements set -euo pipefail to exit immediately on errors, an INSTALL_PHASE variable to track execution context, and a cleanup_on_error trap that reports the failing phase. Additionally, ods_model_lifecycle_lock_acquire creates an atomic lock before model downloads (lines 45–47), preventing concurrent installer instances from corrupting shared resources.

How can I run the ODS installer in offline or cloud-only mode?

For offline mode, use the --offline flag to skip network-dependent steps (handled in Phase 09 via installers/phases/09-offline.sh). For cloud deployments, use --cloud combined with --external-llm-url and --external-llm-provider flags to bypass local GPU detection and use external LLM services instead of local containerized models.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →