Docker docs, compose defaults, scripts and the file test name the 0.2.7 image tags (0.2.7-cuda13 and the other flavors)

This commit is contained in:
Niko1221 committed 2026-10-27 01:25:46 +01:00
1 parent 1d45da3a8a
commit df20d77845
11 files changed
+43 -43

No files matched your search

+1 -1
View File
@@ -13,7 +13,7 @@ on:
workflow_dispatch:
inputs:
release_tag:
description: 'Release tag whose engine packages go into the images (for example v0.2.3)'
description: 'Release tag whose engine packages go into the images (for example v0.2.7)'
required: true
type: string
flavors:
+2 -2
View File
@@ -5,13 +5,13 @@
#
# Build it with docker/build.sh (it assembles the build context: the Terminal sources and the package folder):
#
# docker/build.sh --flavor cuda --engine /path/to/0.1.45.3-linux-x86_64-cuda-cuda13 --tag strata:0.2.3-cuda13
# docker/build.sh --flavor cuda --engine /path/to/0.1.45.3-linux-x86_64-cuda-cuda13 --tag strata:0.2.7-cuda13
#
# Plain `docker build` also works when the context folder has this layout (build.sh makes it):
# terminal-src/ the files package_terminal.py needs (packaging/, strata_cli/, strata_control/, serve/, tools/, data/, ...)
# engine/ one folder per engine package, exactly as `package_engine.py` wrote it (engine-component.json inside)
# docker/ entrypoint.sh, strata-wrapper.sh, healthcheck.sh
# docker build --build-arg FLAVOR=cuda -t strata:0.2.3-cuda13 -f Dockerfile <context>
# docker build --build-arg FLAVOR=cuda -t strata:0.2.7-cuda13 -f Dockerfile <context>
#
# FLAVOR picks the small set of system libraries the runtime image adds and its base:
# cuda NVIDIA: the engine package carries cudart/cublas; the driver's libcuda comes from nvidia-container-toolkit
+3 -3
View File
@@ -2,9 +2,9 @@
# Build a Strata image from an engine component package. Run it on a Linux x86_64 machine with Docker (it needs the internet
# for the base image and for the Terminal's pinned Python and locked wheels; the engine package is local).
#
# docker/build.sh --flavor cuda --engine ~/pkgs/0.1.45.3-linux-x86_64-cuda-cuda13 --tag strata:0.2.3-cuda13
# docker/build.sh --flavor hip --engine ~/pkgs/0.1.45.3-linux-x86_64-hip-gfx120X --tag strata:0.2.3-rocm-gfx120x
# docker/build.sh --flavor sycl --engine ~/pkgs/0.1.45.3-linux-x86_64-sycl --tag strata:0.2.3-sycl
# docker/build.sh --flavor cuda --engine ~/pkgs/0.1.45.3-linux-x86_64-cuda-cuda13 --tag strata:0.2.7-cuda13
# docker/build.sh --flavor hip --engine ~/pkgs/0.1.45.3-linux-x86_64-hip-gfx120X --tag strata:0.2.7-rocm-gfx120x
# docker/build.sh --flavor sycl --engine ~/pkgs/0.1.45.3-linux-x86_64-sycl --tag strata:0.2.7-sycl
#
# --engine is the package FOLDER that packaging/package_engine.py wrote (engine-component.json inside). It can be given more than
# once to put several packages in one image (the Terminal picks the one that fits the card).
+1 -1
View File
@@ -1,5 +1,5 @@
# Copy to .env next to the compose file you use. Every line is optional.
# STRATA_IMAGE=strata:0.2.3-cuda13 # only to use an image you built yourself (docker/build.sh); the default is the published ghcr.io/niko1221/strata image
# STRATA_IMAGE=strata:0.2.7-cuda13 # only to use an image you built yourself (docker/build.sh); the default is the published ghcr.io/niko1221/strata image
# MODEL=IQ3_XXS
# MODEL_PATH=/models # with a volume line - /srv/gguf/IQ3_XXS:/models:ro
# CONTEXT=32k
+2 -2
View File
@@ -4,10 +4,10 @@
# cp .env.example .env
# docker compose -f docker-compose.amd.yml up -d
#
# Images: ghcr.io/niko1221/strata (published from 0.2.1 on). To use one you built yourself: STRATA_IMAGE=strata:0.2.3-<flavor> docker compose up -d
# Images: ghcr.io/niko1221/strata (published from 0.2.1 on). To use one you built yourself: STRATA_IMAGE=strata:0.2.7-<flavor> docker compose up -d
services:
strata:
image: ${STRATA_IMAGE:-ghcr.io/niko1221/strata:0.2.3-rocm-gfx120x}
image: ${STRATA_IMAGE:-ghcr.io/niko1221/strata:0.2.7-rocm-gfx120x}
container_name: strata
restart: unless-stopped
ports:
+2 -2
View File
@@ -4,10 +4,10 @@
# cp .env.example .env
# docker compose -f docker-compose.intel.yml up -d
#
# Images: ghcr.io/niko1221/strata (published from 0.2.1 on). To use one you built yourself: STRATA_IMAGE=strata:0.2.3-<flavor> docker compose up -d
# Images: ghcr.io/niko1221/strata (published from 0.2.1 on). To use one you built yourself: STRATA_IMAGE=strata:0.2.7-<flavor> docker compose up -d
services:
strata:
image: ${STRATA_IMAGE:-ghcr.io/niko1221/strata:0.2.3-sycl}
image: ${STRATA_IMAGE:-ghcr.io/niko1221/strata:0.2.7-sycl}
container_name: strata
restart: unless-stopped
ports:
+2 -2
View File
@@ -5,10 +5,10 @@
# docker compose -f docker-compose.nvidia.yml logs -f # the first start downloads the model (resumable)
#
# Image: cuda13 for RTX 20-50 with driver 580 or newer; cuda12 for Pascal / Volta (GTX 10, Tesla P100, V100) or drivers 575-579.
# Images: ghcr.io/niko1221/strata (published from 0.2.1 on). To use one you built yourself: STRATA_IMAGE=strata:0.2.3-<flavor> docker compose up -d
# Images: ghcr.io/niko1221/strata (published from 0.2.1 on). To use one you built yourself: STRATA_IMAGE=strata:0.2.7-<flavor> docker compose up -d
services:
strata:
image: ${STRATA_IMAGE:-ghcr.io/niko1221/strata:0.2.3-cuda13}
image: ${STRATA_IMAGE:-ghcr.io/niko1221/strata:0.2.7-cuda13}
container_name: strata
restart: unless-stopped
ports:
+3 -3
View File
@@ -1,9 +1,9 @@
#!/usr/bin/env python3
"""Fetch the engine packages for the Docker images from a release, checked against the signed update feed.
python3 docker/fetch-engines.py --release-tag v0.2.3 --flavors cuda13,cuda12,rocm-gfx120x --out ./pkgs
python3 docker/fetch-engines.py --release-tag v0.2.7 --flavors cuda13,cuda12,rocm-gfx120x --out ./pkgs
python3 docker/fetch-engines.py --source /path/to/release-folder --flavors cuda13 --out ./pkgs
python3 docker/fetch-engines.py --release-tag v0.2.3 --list
python3 docker/fetch-engines.py --release-tag v0.2.7 --list
What it does, in the same order and with the same code as `strata update`:
@@ -98,7 +98,7 @@ def fetch_one(feed: feedmod.Feed, pkg: feedmod.EnginePackage, out: Path, trusted
def main() -> int:
ap = argparse.ArgumentParser(description=__doc__.split("\n\n")[0])
ap.add_argument("--release-tag", help="the GitHub release tag, for example v0.2.3")
ap.add_argument("--release-tag", help="the GitHub release tag, for example v0.2.7")
ap.add_argument("--repo", default="Niko1221/Strata", help="owner/name of the GitHub repository (default %(default)s)")
ap.add_argument("--source", help="a release folder or base URL holding strata-feed.json(.sig) and the archives (instead of --release-tag)")
ap.add_argument("--flavors", default=",".join(FLAVORS), help="comma separated; default: all (%s)" % ", ".join(FLAVORS))
+4 -4
View File
@@ -2,9 +2,9 @@
# Build the Strata images of one release from its engine packages and, only with --push, push them to the registry.
# The GitHub Actions workflow (.github/workflows/docker-images.yml) runs this script once per flavor; you can run it by hand too.
#
# docker/publish.sh --release-tag v0.2.3 # builds every flavor the release has a package for; pushes nothing
# docker/publish.sh --release-tag v0.2.3 --flavors cuda13,cuda12 --push
# docker/publish.sh --source ~/release-folder --version 0.2.3-test --flavors cuda13 --no-latest
# docker/publish.sh --release-tag v0.2.7 # builds every flavor the release has a package for; pushes nothing
# docker/publish.sh --release-tag v0.2.7 --flavors cuda13,cuda12 --push
# docker/publish.sh --source ~/release-folder --version 0.2.7-test --flavors cuda13 --no-latest
#
# For every flavor:
# 1. docker/fetch-engines.py downloads the engine package from the release (a GitHub release URL, or --source) and checks it
@@ -15,7 +15,7 @@
# 4. with --push: docker push of <image>:<version>-<flavor> and, unless --no-latest, <image>:latest-<flavor>. You must be logged in
# to the registry already (`docker login ghcr.io`; the workflow logs in with GITHUB_TOKEN).
#
# --release-tag TAG the release, for example v0.2.3; the image version is the tag without the leading v
# --release-tag TAG the release, for example v0.2.7; the image version is the tag without the leading v
# --source DIR|URL use this folder or URL (with strata-feed.json, its .sig and the archives) instead of the GitHub release
# --version V image version (default: the tag without v)
# --flavors LIST comma separated (default: all that the release has: cuda13 cuda12 rocm-gfx120x rocm-gfx110x rocm-gfx1151 sycl)
+19 -19
View File
@@ -17,12 +17,12 @@ Docker on a **Mac** has no access to the Mac's graphics chip (no Metal): use the
| Your graphics card | Image tag | Needs on the computer |
| --- | --- | --- |
| NVIDIA **RTX 20, 30, 40, 50** series (and the matching RTX A / Quadro cards) | `0.2.3-cuda13` | NVIDIA driver **580 or newer**, [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) |
| NVIDIA **GTX 10 (Pascal), Tesla P100, V100 (Volta)**, or any NVIDIA card whose driver is **575 to 579** | `0.2.3-cuda12` | NVIDIA driver **575 or newer**, the same toolkit |
| AMD **RX 9000** series and Radeon AI PRO R9700 (RDNA 4, gfx1200 / gfx1201) | `0.2.3-rocm-gfx120x` | the `amdgpu` kernel driver (Linux 6.8+) |
| AMD **RX 7000** series (RDNA 3, gfx1100 / gfx1101 / gfx1102) | `0.2.3-rocm-gfx110x` | the `amdgpu` kernel driver |
| AMD **Ryzen AI Max** ("Strix Halo", Radeon 8060S, gfx1151) | `0.2.3-rocm-gfx1151` | the `amdgpu` kernel driver |
| Intel **Arc** A-series and B-series (including Arc Pro B70) | `0.2.3-sycl` (if no image exists for a release, [build it](#build-it-yourself)) | the `i915` or `xe` kernel driver; **prepared model files** (see [Intel](#intel-arc)) |
| NVIDIA **RTX 20, 30, 40, 50** series (and the matching RTX A / Quadro cards) | `0.2.7-cuda13` | NVIDIA driver **580 or newer**, [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html) |
| NVIDIA **GTX 10 (Pascal), Tesla P100, V100 (Volta)**, or any NVIDIA card whose driver is **575 to 579** | `0.2.7-cuda12` | NVIDIA driver **575 or newer**, the same toolkit |
| AMD **RX 9000** series and Radeon AI PRO R9700 (RDNA 4, gfx1200 / gfx1201) | `0.2.7-rocm-gfx120x` | the `amdgpu` kernel driver (Linux 6.8+) |
| AMD **RX 7000** series (RDNA 3, gfx1100 / gfx1101 / gfx1102) | `0.2.7-rocm-gfx110x` | the `amdgpu` kernel driver |
| AMD **Ryzen AI Max** ("Strix Halo", Radeon 8060S, gfx1151) | `0.2.7-rocm-gfx1151` | the `amdgpu` kernel driver |
| Intel **Arc** A-series and B-series (including Arc Pro B70) | `0.2.7-sycl` (if no image exists for a release, [build it](#build-it-yourself)) | the `i915` or `xe` kernel driver; **prepared model files** (see [Intel](#intel-arc)) |
**Measured on:** images built from the 0.1.45 engine packages. Size on disk: `cuda13` 2.2 GB, `cuda12` 2.9 GB, `rocm-gfx120x` 2.8 GB,
`rocm-gfx110x` 2.4 GB, `rocm-gfx1151` 1.5 GB. The download is about a third of that: `cuda13` 640 MB, `cuda12` 845 MB,
@@ -32,9 +32,9 @@ Not sure which NVIDIA image? Take `cuda13` when `nvidia-smi` shows driver 580 or
A wrong pick does no harm: the container starts, says in plain words that the engine does not fit this card, and stops.
**Ready-made images are published from version 0.2.1 on**, to the GitHub Container Registry: `ghcr.io/niko1221/strata:<version>-<flavor>`
(for example `0.2.3-cuda13`), and `ghcr.io/niko1221/strata:latest-<flavor>` for the newest release of that flavor. Pin the version
(for example `0.2.7-cuda13`), and `ghcr.io/niko1221/strata:latest-<flavor>` for the newest release of that flavor. Pin the version
tag if you want updates only when you decide. The examples below use these images. If you built an image yourself
([Build it yourself](#build-it-yourself)), use the tag you gave it (for example `strata:0.2.3-cuda13`) in their place.
([Build it yourself](#build-it-yourself)), use the tag you gave it (for example `strata:0.2.7-cuda13`) in their place.
## One command per card
@@ -49,7 +49,7 @@ downloaded for the model itself ([Files you already have](#files-you-already-hav
docker run -d --name strata --gpus all -p 127.0.0.1:8080:8080 \
--ulimit memlock=-1:-1 --shm-size 2g --stop-timeout 120 \
-v strata-data:/data -e FAMILY=qwen -e MODEL=IQ3_XXS -e API_KEY=$(openssl rand -hex 24) \
ghcr.io/niko1221/strata:0.2.3-cuda13
ghcr.io/niko1221/strata:0.2.7-cuda13
```
**AMD**
@@ -59,7 +59,7 @@ docker run -d --name strata --device /dev/kfd --device /dev/dri \
--group-add video --group-add $(getent group render | cut -d: -f3) -p 127.0.0.1:8080:8080 \
--ulimit memlock=-1:-1 --shm-size 2g --stop-timeout 120 \
-v strata-data:/data -e FAMILY=qwen -e MODEL=IQ3_XXS -e API_KEY=$(openssl rand -hex 24) \
ghcr.io/niko1221/strata:0.2.3-rocm-gfx120x
ghcr.io/niko1221/strata:0.2.7-rocm-gfx120x
```
**Intel Arc**
@@ -68,7 +68,7 @@ docker run -d --name strata --device /dev/kfd --device /dev/dri \
docker run -d --name strata --device /dev/dri --group-add $(getent group render | cut -d: -f3) \
-p 127.0.0.1:8080:8080 --ulimit memlock=-1:-1 --shm-size 2g --stop-timeout 120 \
-v strata-data:/data -e FAMILY=qwen -e MODEL=IQ3_S -e MODEL_PATH=/models -v /srv/gguf/IQ3_S:/models:ro \
-e API_KEY=$(openssl rand -hex 24) ghcr.io/niko1221/strata:0.2.3-sycl
-e API_KEY=$(openssl rand -hex 24) ghcr.io/niko1221/strata:0.2.7-sycl
```
What the options are for: `--ulimit memlock=-1:-1` lets the engine pin the RAM it uses for the model, `--shm-size 2g` gives
@@ -206,7 +206,7 @@ The health check asks `GET /v1/models` with the key. During the first download t
## Updating
```sh
docker pull ghcr.io/niko1221/strata:0.2.3-cuda13 # the new tag (with a self-built image, build it again instead)
docker pull ghcr.io/niko1221/strata:0.2.7-cuda13 # the new tag (with a self-built image, build it again instead)
docker stop strata && docker rm strata
# run the same docker run command again with the new tag (compose: docker compose pull && docker compose up -d)
```
@@ -288,9 +288,9 @@ This is the way to get an image for a computer without registry access or after
folder (made by `packaging/package_engine.py`, or fetched by `strata update` into a components folder) and Docker on Linux:
```sh
docker/build.sh --flavor cuda --engine ~/components/engine/<cuda13-package-folder> --tag strata:0.2.3-cuda13
docker/build.sh --flavor hip --engine ~/components/engine/<hip-rx9070-package-folder> --tag strata:0.2.3-rocm-gfx120x
docker/build.sh --flavor sycl --engine ~/components/engine/<sycl-package-folder> --tag strata:0.2.3-sycl
docker/build.sh --flavor cuda --engine ~/components/engine/<cuda13-package-folder> --tag strata:0.2.7-cuda13
docker/build.sh --flavor hip --engine ~/components/engine/<hip-rx9070-package-folder> --tag strata:0.2.7-rocm-gfx120x
docker/build.sh --flavor sycl --engine ~/components/engine/<sycl-package-folder> --tag strata:0.2.7-sycl
```
`build.sh` assembles the build context (the Terminal's files and the package) and runs `docker build`. The build makes the
@@ -316,13 +316,13 @@ files the signed update feed names. Nothing publishes by itself: a maintainer st
1. Make the release first (its `strata-feed.json`, `strata-feed.json.sig` and the engine archives must be on the GitHub release).
2. GitHub, **Actions, Docker images, Run workflow** ([.github/workflows/docker-images.yml](../.github/workflows/docker-images.yml); the file has to be on
the default branch to show up). Inputs: the release tag (`v0.2.3`), the flavors (empty: every flavor the release has a package
the default branch to show up). Inputs: the release tag (`v0.2.7`), the flavors (empty: every flavor the release has a package
for), **push** and **latest**. Run it once with **push off**: it builds every image and publishes nothing (a dry run).
3. Run it again with **push on**. It logs in to `ghcr.io` with the job's `GITHUB_TOKEN` (`packages: write`) and pushes
`ghcr.io/niko1221/strata:0.2.3-<flavor>` and `latest-<flavor>`. Turn **latest** off for a pre-release.
`ghcr.io/niko1221/strata:0.2.7-<flavor>` and `latest-<flavor>`. Turn **latest** off for a pre-release.
4. The first push creates each package as private. In the repository's Packages, open every package, **Package settings, Change
visibility, Public**, and check it is linked to the repository (the image carries the `org.opencontainers.image.source` label).
5. Check one pull from a computer that is not logged in: `docker pull ghcr.io/niko1221/strata:0.2.3-cuda13`.
5. Check one pull from a computer that is not logged in: `docker pull ghcr.io/niko1221/strata:0.2.7-cuda13`.
For each flavor the job runs [docker/fetch-engines.py](../docker/fetch-engines.py), which reads the release's signed feed (the
Ed25519 key in `strata_control/update_keys.json`), downloads the package, and checks the archive's size and SHA-256, the manifest
@@ -340,7 +340,7 @@ the job starts the image once to see that the Terminal inside it runs.
| `sycl` | `linux-x86_64`, sycl; only when the feed lists one |
A flavor the feed has no package for is left out, with a line in the log. The same steps run from a Linux computer with Docker:
`docker/publish.sh --release-tag v0.2.3` builds everything and pushes nothing; add `--push` (after `docker login ghcr.io`) to publish.
`docker/publish.sh --release-tag v0.2.7` builds everything and pushes nothing; add `--push` (after `docker login ghcr.io`) to publish.
The images run on the runner without a graphics card, so the card checks (`docker/smoke-test.sh`) stay a manual step on a computer with the card.
## Known limits
+4 -4
View File
@@ -205,10 +205,10 @@ class Document(unittest.TestCase):
def test_tags_in_the_document_match_the_compose_defaults(self):
doc = (ROOT / "docs" / "DOCKER.md").read_text(encoding="utf-8")
for tag in ("0.2.3-cuda13", "0.2.3-cuda12", "0.2.3-rocm-gfx120x", "0.2.3-rocm-gfx110x", "0.2.3-rocm-gfx1151", "0.2.3-sycl"):
for tag in ("0.2.7-cuda13", "0.2.7-cuda12", "0.2.7-rocm-gfx120x", "0.2.7-rocm-gfx110x", "0.2.7-rocm-gfx1151", "0.2.7-sycl"):
self.assertIn(tag, doc)
for name, tag in (("docker-compose.nvidia.yml", "ghcr.io/niko1221/strata:0.2.3-cuda13"), ("docker-compose.amd.yml", "ghcr.io/niko1221/strata:0.2.3-rocm-gfx120x"),
("docker-compose.intel.yml", "ghcr.io/niko1221/strata:0.2.3-sycl")):
for name, tag in (("docker-compose.nvidia.yml", "ghcr.io/niko1221/strata:0.2.7-cuda13"), ("docker-compose.amd.yml", "ghcr.io/niko1221/strata:0.2.7-rocm-gfx120x"),
("docker-compose.intel.yml", "ghcr.io/niko1221/strata:0.2.7-sycl")):
self.assertIn(tag, (DOCKER / "compose" / name).read_text(encoding="utf-8"))
def test_the_user_doc_says_images_are_published_from_0_2_1(self):
@@ -239,7 +239,7 @@ class Publishing(unittest.TestCase):
doc = (ROOT / "docs" / "DOCKER.md").read_text(encoding="utf-8")
self.assertTrue({"cuda13", "cuda12", "rocm-gfx120x", "rocm-gfx110x", "rocm-gfx1151", "sycl"} <= set(flavors), flavors)
for flavor in flavors:
self.assertIn(f"0.2.3-{flavor}", doc)
self.assertIn(f"0.2.7-{flavor}", doc)
def test_build_script_copies_everything_the_terminal_package_needs(self):
"""docker/build.sh lists the Terminal's files by hand; the list must cover package_terminal.py's payload (it once missed docs/TERMINAL_LAUNCH.md)."""