Skip to content

Installation and Configuration

yellowbean edited this page Oct 19, 2026 · 1 revision

Installation and Configuration

How to run the Hastructure engine locally, in a container, or from a prebuilt binary — and what config.yml supports.

From Docker (recommended)

Pull from Docker Hub; the image path is yellowbean/hastructure (full registry path docker.io/yellowbean/hastructure). See Release Management for which track publishes which tag:

image tag track freshness
yellowbean/hastructure:latest v* release tags only refreshed when a v-tag is pushed
yellowbean/hastructure:dev a* dev tags + merged PRs freshest build
yellowbean/hastructure:v<version> / :<version> per release pinned
yellowbean/hastructure:a<version> per dev release pinned, multi-arch

Production / stable:

docker pull yellowbean/hastructure:latest
docker run -p 8081:8081 yellowbean/hastructure:latest

Development:

docker pull yellowbean/hastructure:dev
docker run -p 8081:8081 yellowbean/hastructure:dev

Or build from a checkout (first run compiles GHC inside the image, allow time):

docker compose up --build

The image ships Hastructure-exe, config.yml and swagger.json in /opt/myapp. The engine reads config.yml from its working directory once at startup and refuses to start when the file is missing, malformed or contains an invalid value. To change server settings, mount your own config — the port in the mounted file must equal the host-side port mapping:

# example: config.yml with `port: 9090`
docker run -p 9090:9090 -v "$PWD/config.yml:/opt/myapp/config.yml" yellowbean/hastructure:latest

Verify the engine is up:

curl -s localhost:8081/version     # {"_version":"0.52.x"}

From nix

nix-shell shell.nix                     # dev shell: GHC, HLS, cabal
nix-build release.nix -A hastructure    # build the engine -> result/bin/Hastructure-exe

From release executables

Prebuilt executables are attached to GitHub releases:

  • new naming (CI of Oct 2026+): Hastructure-<tag>-<os-arch> — e.g. Hastructure-v0.52.13-linux-amd64, -linux-arm64, -macos-arm64, -windows-amd64(.exe)
  • historical releases carry Hastructure-<version>-<OS>-ghc-<ghc-version> names
chmod +x Hastructure-<version>-linux-amd64
./Hastructure-<version>-linux-amd64

Run it from a directory containing config.yml (same startup rules as in the container).

Configuration (config.yml)

Sample: config.yml in the repository. The file is read once at startup — restart the process to apply changes.

port: 8081
# workerNum: 8   # in-flight cap per multi-run request; default: HASTRUCTURE_WORKERS env, else RTS -N
maxRunNum:       # per-endpoint total-run caps per request; default 1000 each, non-positive values abort startup
  runPoolByScenarios: 1000
  runDealByScenarios: 1000
  runMultiDeals: 1000
  runDealByRunScenarios: 1000
  runByCombo: 1000
field required meaning
port yes HTTP listen port; missing port aborts startup
workerNum no in-flight evaluation cap applied to every multi-run request. Precedence: HASTRUCTURE_WORKERS environment variable (when it parses to a positive integer), then workerNum, then the RTS capability count (+RTS -N). A present-but-unusable value falls back to the next layer — it is only a performance knob
maxRunNum.<endpoint> no per-endpoint total-run caps, default 1000 each; a non-positive value aborts startup

maxRunNum keys cover the five multi-run endpoints:

  • runPoolByScenarios — number of pool scenarios
  • runDealByScenarios — number of deal scenarios
  • runMultiDeals — number of deals
  • runDealByRunScenarios — number of non-performance assumption scenarios
  • runByCombo — size of the deals × assumptions × non-performance assumptions cartesian product (sized before materialising, so oversized grids are rejected without allocation)

Exceeding a cap is rejected with HTTP 400 in the standard JSON error envelope, naming the endpoint, the configured limit and the key to raise:

{"Left":"runByCombo would run 8 runs, exceeding maxRunNum.runByCombo 2 (config.yml); reduce the request size or raise maxRunNum.runByCombo in config.yml and restart the engine"}

Invalid config values abort startup with an invalid config.yml: ... error naming the offending key.

REST API and client compatibility

  • OpenAPI description: swagger.json
  • Endpoints: version, runDeal, runPool, runPoolByScenarios, runDealByScenarios, runMultiDeals, runDealByRunScenarios, runByCombo, runByRootFinder, runAsset, runDate
  • Error contract: failures are returned as {"Left":"<reason>"} (in-band for single-run endpoints, HTTP 400/500 JSON envelope otherwise)
  • The official Python wrapper is absbox; it checks the MAJOR.MINOR pair at connect time (0.52.x client ↔ 0.52.x engine), PATCH differences are always compatible

Clone this wiki locally