Skip to content
Alvo is pre-v0.1: the image runs from its edge tag, and no NuGet package or release is published yet.Pre-v0.1: no release yet.Roadmap and status

Standalone and embedded

Understand the two ways to run Alvo, a container driven by a descriptor or packages inside your own ASP.NET Core app, what each gives you, and how to choose.

Alvo is one engine with two distributions. Standalone, it is a container image that turns a mounted descriptor into a running backend, with a dashboard and an API browser. Embedded, it is a set of NuGet packages you add to your own ASP.NET Core app, next to your own endpoints and your own users. The standalone image is itself an ASP.NET Core host built from those same packages, so the two cannot drift apart: at its centre are AddAlvo(…) and MapAlvo(), exactly what an embedded host calls, plus the dashboard, sign-in and an API browser around them.

You bring a descriptor and configuration; the image brings everything else.

  • The image reads the descriptor from /alvo/descriptor.json, runs on PostgreSQL or SQLite chosen by configuration, and listens on port 8080. It is published as ghcr.io/burgyn/alvo; pre-v0.1 it is tagged edge, built from main.
  • The quick start’s compose file runs it over PostgreSQL 16: Quick start starts it, Run your own descriptor points it at yours.
  • The dashboard at /admin, with the schema assistant when a model is connected, and people who sign in with a password.
  • The API browser at /scalar, over the OpenAPI document the descriptor generates at /openapi/v1.json.
  • The Management API at /management, for agents and scripts.

Everything is configuration: API keys, the bootstrap administrator, the database, the startup mode. Running in production covers what to set.

Your app owns the process, and Alvo is a part of it.

  • Packages: MMLib.Alvo and one database provider, MMLib.Alvo.Data.Sqlite or MMLib.Alvo.Data.PostgreSql. They are not on NuGet before v0.1; today you reference the projects or pack them to a local feed (Embed in ASP.NET Core).
  • Registration: AddAlvo(alvo => alvo.UseSqlite(…).FromDescriptor(path)), then map what you want where you want it: the generated Data API under a prefix of your choice, the health probes, the Management API.
  • Your authentication: your users reach Alvo’s data through your own endpoints, which pass Alvo the caller and let the descriptor’s rules decide (Use your own authentication).
  • Your endpoints: they call IAlvoData in process, under the same rules as the generated API (Call Alvo from your endpoints).
  • Your C#: functions a descriptor’s hooks can call, registered with AddCelFunction (Custom CEL functions).

The dashboard (MMLib.Alvo.Admin) and the schema assistant (MMLib.Alvo.Ai) are separate packages a host can add; the one-file host in Embed Alvo in ASP.NET Core adds them as an optional step.

The descriptor is the same file in either mode: the image mounts it, an embedded host passes its path to FromDescriptor. The repository proves it rather than claiming it. examples/vehicle-registry is the descriptor the compose stack serves and the one the embedded sample, samples/MMLib.Alvo.Samples.EmbeddedHost, runs; the sample’s integration suite boots both and asserts that they generate the same routes.

So moving from standalone to embedded is carrying the file over. The signal to move is needing code: your own functions, endpoints, identity or providers. That is an upgrade path, not a limit of the standalone mode.

StandaloneEmbedded
Distributionthe container image ghcr.io/burgyn/alvo (edge until v0.1)NuGet packages, project references until v0.1
Descriptorthe file mounted at /alvo/descriptor.jsonthe path you pass to FromDescriptor
DatabasePostgreSQL or SQLite, chosen by Alvo:Database:Providerthe provider package you register
Generated APIat /apiunder the prefix you choose (/api/alvo in Embed Alvo in ASP.NET Core), with your own conventions attached
Who calls the generated APIAPI keys from configurationAPI keys; your own users go through your endpoints
Custom CEL functionsbuilt-in functions onlybuilt-ins plus your AddCelFunction registrations
Your own endpointsnoneyes, through IAlvoData
OpenAPI document and API browser/openapi/v1.json and /scalar, switched by Alvo:Docs:Enablednone of its own: call AddOpenApi() and MapOpenApi(), and Alvo’s routes and schemas appear in your document
Dashboard and schema assistantincluded, at /adminadd MMLib.Alvo.Admin and MMLib.Alvo.Ai
ConfigurationAlvo:* keys, environment variables in the containerthe same options, bound or set in code
Errorsevery problem typeevery problem type except unreadable-request, internal and function-failed, which need AddAlvoProblemDetails()
Health probes/health/live and /health/readythe same two, where you map them

The error row matters for clients. Alvo’s own endpoints answer their refusals as problem documents in both modes. The three types in that row are produced by Alvo’s exception handler, which an embedded host opts into with AddAlvoProblemDetails(); without it, your host renders a request the web server refused, a failure inside Alvo, or a failing CEL function its own way. Handle errors shows both.