Repository navigation
Installation and Configuration
How to run the Hastructure engine locally, in a container, or from a
prebuilt binary — and what config.yml supports.
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:latestDevelopment:
docker pull yellowbean/hastructure:dev
docker run -p 8081:8081 yellowbean/hastructure:devOr build from a checkout (first run compiles GHC inside the image, allow time):
docker compose up --buildThe 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:latestVerify the engine is up:
curl -s localhost:8081/version # {"_version":"0.52.x"}nix-shell shell.nix # dev shell: GHC, HLS, cabal
nix-build release.nix -A hastructure # build the engine -> result/bin/Hastructure-exePrebuilt 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-amd64Run it from a directory containing config.yml (same startup rules as in the
container).
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.
- 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 theMAJOR.MINORpair at connect time (0.52.xclient ↔0.52.xengine), PATCH differences are always compatible