containers - mvx-lang/mvx GitHub Wiki
Containers
Two images ship MVX to Docker, built from docker/ in the repo:
| image | what it is |
|---|---|
mvx |
the base system — compiler, shell, runtime, drivers, standard verbs |
mvx-demo |
a ready-to-run account with the example programs cataloged |
There was a third, mvx-lmdbd, until mvx#327 removed the daemon. A shared
database is now a stock postgres image.
Build both (base first, since the demo layers on it):
docker/build.sh # ghcr.io/mvx-lang/mvx{,-demo}:latest
REGISTRY=you TAG=0.1 docker/build.sh # custom namespace / tag
PUSH=1 docker/build.sh # build, then docker push each
Each has its own Dockerfile (docker/Dockerfile.base, .demo) if you
prefer to build them one at a time. The demo FROMs the base via a BASE
build-arg (default mvx), so a published base can be layered on directly.
On a v* git tag, the release GitHub Actions workflow builds and pushes
both images multi-arch (linux/amd64 and linux/arm64) to the GitHub
Container Registry under ghcr.io/mvx-lang/, alongside the native Linux
binary tarballs — see Publishing.
mvx — the base system
A multi-stage build compiles MVX against LLVM and installs it to
/usr/local, then a slim runtime layer keeps the install plus a C
toolchain (mvx-basic shells out to cc to link programs). mvx is on
PATH, and it locates its runtime, drivers, and system account relative
to itself — no environment variables.
docker run --rm -it mvx # MVX shell in a scratch /work account
docker run --rm mvx mvx-basic -h # or run any tool directly
docker run --rm -v "$PWD":/src mvx \
mvx-basic /src/prog.b -o /src/prog # compile a program from a bind mount
It defaults to the developer privilege tier so BASIC, CATALOG,
and COMPILE() work. Use it as the base for your own account images.
Compose: a shared database, local application code
docker/compose.demo.yaml wires a postgres server to two application
accounts, modelling the classic MultiValue split: each app keeps its VOC
and BP (source) in a local database, while the data files live on the
shared server — so both apps read and write the same records.
docker compose -f docker/compose.demo.yaml up -d
Services:
-
mvxdb— a stockpostgres:16-alpine; its data persists on a volume. -
init— a one-shot that defines the connection profile, creates the sharedORDERSandCUSTOMERSfiles through it, seeds a few records, then exits. -
app1,app2— application accounts. Each creates a localVOCandBP, defines the same profile, then writes aBINDINGSrecord soORDERSandCUSTOMERSresolve to the server:ORDERS @shared CUSTOMERS @sharedThe address and the password are not in
BINDINGS— it names only the profile, so it is committable. The profile holds the address, and the password arrives asMVXCONN_SHARED_PASSWORDfrom the environment rather than being written to disk.
Log on to either and the picture is the same shared data:
docker compose -f docker/compose.demo.yaml exec app1 mvx -a /acct
app1> LISTF
File Type
BP sqlite # local to app1
VOC sqlite # local to app1
ORDERS postgres # shared, on mvxdb
CUSTOMERS postgres # shared, on mvxdb
app1> COUNT ORDERS
2 record(s) counted
A record written from app1 is visible from app2 immediately — they are
the same table on the one server — while each app's cataloged verbs and
source stay private to its own account. The per-file BINDINGS record is
how a second account attaches to a data file the first one created.
mvx-demo — the example account
Boots straight into a /demo account with the example programs
cataloged as verbs. Give it a TTY so the full-screen programs render:
docker run --rm -it ghcr.io/mvx-lang/mvx-demo # or just `mvx-demo` if built locally
demo> SNAKE # arrows steer; q or ESC quits
demo> FSDEMO # the Midnight Commander-style full-screen demo
Both are ordinary cataloged BASIC — LISTF, LIST BP, or VI BP SNAKE
to look under the hood.
Publishing
Releases are automated and need no external accounts or secrets.
Pushing a v* tag runs the release workflow, which publishes both
images multi-arch to the GitHub Container Registry under
ghcr.io/mvx-lang/ — authenticating with the built-in GITHUB_TOKEN —
and attaches per-architecture Linux binary tarballs to the GitHub
release:
git tag v0.1.0 && git push origin v0.1.0
The packages are created private; make each public once from the org's
Packages settings (or the package page → Package settings →
Change visibility) so docker pull ghcr.io/mvx-lang/mvx-demo works
without a login. To publish by hand instead, docker/build.sh tags
images ${REGISTRY}/mvx{,-demo}:${TAG} (REGISTRY defaults to
ghcr.io/mvx-lang); docker login ghcr.io, then run with PUSH=1.