INSTALL GUIDE
AGPL-3.0 · SELF-HOSTED · YOUR KEYS

Install

One command, and a stack that checks its own work.

oshal runs on one machine with Docker — cockpit, database, mesh, vector store and the bot fleet — and the installer refuses to tell you it worked until it has verified that it did. No cloud account, no API key to begin with, nothing to compile.

Before you start

What the machine needs.

REQ Docker Desktop, with Compose v2The installer checks for the docker command, docker compose version, and a running daemon, and stops if any is missing. On Windows it can install Docker Desktop for you through winget.
REQ 6 GB of RAM for the engine, 10 GB to be comfortableMeasured footprint from the install guide. The bring-up starts bots in small batches specifically because a mass cold start OOM-crashed a 6 GB engine twice — so the minimum is real, not defensive.
REQ About 25 GB of free diskImages account for roughly 12 GB of that. Allow 40 GB if you plan to build from source rather than pull.
OPT Git — only if you build from sourcePulling prebuilt images needs no git. The from-source mode clones the repo and builds, and checks for git before it starts.
OPT Nothing elseNo Node, no Python, no Postgres, no cloud account, no API key to begin with. Everything the platform needs runs in the compose stack.

Three ways in

Pick the one that matches your machine.

Path A

macOS or Linux — one command

Downloads the installer and runs it. It asks you three things (which mode, which bundle of apps, and an email for the first account), then does the rest.

curl -fsSLO https://raw.githubusercontent.com/emeraldcoastsystemsgroup/oshal/main/scripts/oshal-install.sh bash oshal-install.sh
Path B

Windows — double-click

For a machine with no terminal. Download the launcher and double-click it; it fetches the PowerShell installer and runs the same flow, asking only for an email. Windows SmartScreen will warn that the file is unsigned — choose More info → Run anyway.

Install-OSHAL.bat
Path C

Air-gapped — from an archive

A prebuilt archive carries the images so the install needs no registry and no network. Both installers detect an archive sitting next to them, or you can point at one explicitly. The archive is several gigabytes and is self-hosted rather than attached to a GitHub release.

bash oshal-install.sh --from-archive ./oshal-images.tar

What it does

Six things, in this order.

Worth reading once, because it explains why an oshal install either works or tells you exactly which capability is missing — rather than leaving you with running containers and a blank page.

  1. 01

    It checks the machine before it touches anything

    Docker present, Compose v2 present, daemon actually running. Each is a hard stop with a named reason rather than a failure three minutes into a pull.

  2. 02

    It writes a .env with fresh random secrets

    Database password, session secret, service secret, remote-client secret — generated per install from the system random source. If a .env already exists it keeps yours and says so. This file is the one thing a fresh clone cannot start without.

  3. 03

    It pulls or builds the images and stages the app bundle you chose

    Bundles resolve their dependencies and deduplicate, so choosing full and choosing a themed bundle never stage the same package twice.

  4. 04

    It brings the stack up in order, not all at once

    Infrastructure first and waits for healthy; then the controller, waiting for it to be genuinely up rather than merely answering; then the bot fleet in small batches with a settle between them. Ordering is the difference between a stack that comes up and one that half-starts.

  5. 05

    It verifies by capability and fails the install if one is missing

    A postflight check asks the readiness endpoint for its named legs — model access, bots, credentials, catalogs, voice in and voice out, database — and reports which one is not ready. A green container count is explicitly not treated as success. If the verifier itself cannot be fetched, the installer says the install is unverified rather than claiming success.

  6. 06

    It opens the welcome flow

    At http://localhost:35457/welcome. That is the first-run path — the cockpit itself lives at /cockpit/ once you are through it.

After it finishes

Where everything is.

35457
Cockpit and API. The only port bound to all interfaces, deliberately — it is how another machine joins your swarm. Override with OSHAL_API_PORT.
55433 / 55434
Postgres and the time-series database. Bound to 127.0.0.1 only.
56380
Redis — the agent mesh. Loopback only.
58001
Vector store for retrieval. Loopback only.
58529
Graph tier, when you enable it. Loopback only.
8444
Code server for the shared workspace. Loopback only.
One port is public, the rest are not. Only the cockpit binds to all interfaces, because that is how a second machine joins your swarm. Every datastore is bound to loopback, so nothing on your network can reach your database even if you never configure a firewall.

If something is wrong

The four that actually happen.

  1. 01

    A bare docker compose up on a fresh clone will not start

    Deliberately. There is no session secret and no default identity mode in a clean checkout, and the controller refuses to boot rather than come up insecure. Run the installer, or write a .env first — that single file is the gap between a clone and a running box.

  2. 02

    The cockpit answers on 127.0.0.1 but not localhost

    A stale Windows relay process squatting on the IPv6 loopback. Restarting Docker Desktop does not clear it; killing that process does. The repo carries a runbook for it.

  3. 03

    Everything reports healthy but nothing answers

    Bring the stack up with the ordered script rather than a bare compose command. After an engine restart containers auto-start in the wrong order, and the controller can come up without its database while still passing a shallow health check.

  4. 04

    You want it smaller

    The kernel bundle runs the platform without the full bot fleet. You can install app packages onto it afterwards one at a time.

Next

You have a platform. Now put something on it.

54 applications are installable from the catalog, and adding your own takes a conversation rather than a codebase.