Skip to content

Commit 93bf14d

Browse files
hyperpolymathclaude
andcommitted
feat: add Stapeln container configuration
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3877583 commit 93bf14d

File tree

1 file changed

+271
-0
lines changed

1 file changed

+271
-0
lines changed

stapeln.toml

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# stapeln.toml — Layer-based container build for formatrix-docs
3+
#
4+
# stapeln builds containers as composable layers (German: "to stack").
5+
# Each layer is independently cacheable, verifiable, and signable.
6+
#
7+
# Formatrix Docs is a cross-platform document editor / knowledge tool nexus
8+
# with format tabs (TXT, MD, ADOC, DJOT, ORG, RST, TYP). It comprises a
9+
# Rust core, Gossamer+ReScript GUI, Ada TUI, ArangoDB storage, and Nickel
10+
# pipelines. Optional sidecar services: Vosk (speech-to-text), Tesseract (OCR).
11+
12+
[metadata]
13+
name = "formatrix-docs"
14+
version = "0.1.0"
15+
description = "Cross-platform document editor and knowledge tool nexus with format tabs"
16+
author = "Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>"
17+
license = "PMPL-1.0-or-later"
18+
registry = "ghcr.io/hyperpolymath"
19+
20+
[build]
21+
containerfile = "container/Containerfile"
22+
context = "."
23+
runtime = "podman"
24+
25+
# ── Layer Definitions ──────────────────────────────────────────
26+
27+
[layers.base]
28+
description = "Chainguard Wolfi minimal base"
29+
from = "cgr.dev/chainguard/wolfi-base:latest"
30+
cache = true
31+
verify = true
32+
33+
# ── Rust Build Chain ──────────────────────────────────────────
34+
35+
[layers.rust-toolchain]
36+
description = "Rust compiler and build tooling"
37+
extends = "base"
38+
packages = ["rust", "cargo", "openssl-dev", "pkgconf", "build-base"]
39+
cache = true
40+
41+
[layers.rust-deps]
42+
description = "Pre-cached Rust workspace dependencies"
43+
extends = "rust-toolchain"
44+
commands = [
45+
"mkdir -p /build",
46+
"cp Cargo.toml Cargo.lock /build/",
47+
"cp -r crates /build/crates",
48+
]
49+
workdir = "/build"
50+
cache = true
51+
52+
[layers.rust-build]
53+
description = "Compile Rust workspace crates (core, gui, db, pipeline, bridges)"
54+
extends = "rust-deps"
55+
commands = [
56+
"cargo build --release -p formatrix-core -p formatrix-gui -p formatrix-db -p formatrix-pipeline -p formatrix-bridges",
57+
]
58+
workdir = "/build"
59+
60+
# ── Ada TUI Build Chain ──────────────────────────────────────
61+
62+
[layers.ada-toolchain]
63+
description = "GNAT Ada compiler and gprbuild"
64+
extends = "base"
65+
packages = ["gcc-gnat", "gprbuild", "ncurses-dev", "build-base"]
66+
cache = true
67+
68+
[layers.ada-build]
69+
description = "Compile Ada TUI binary"
70+
extends = "ada-toolchain"
71+
commands = [
72+
"mkdir -p /build/tui",
73+
"cp -r tui /build/tui",
74+
"cd /build/tui && gprbuild -P formatrix_tui.gpr -XMODE=release",
75+
]
76+
workdir = "/build"
77+
78+
# ── Zig FFI Build Chain ─────────────────────────────────────
79+
80+
[layers.zig-toolchain]
81+
description = "Zig compiler for FFI layer"
82+
extends = "base"
83+
packages = ["zig"]
84+
cache = true
85+
86+
[layers.zig-build]
87+
description = "Compile Zig FFI bindings"
88+
extends = "zig-toolchain"
89+
commands = [
90+
"mkdir -p /build/ffi/zig",
91+
"cp -r ffi/zig /build/ffi/zig",
92+
"cd /build/ffi/zig && zig build -Doptimize=ReleaseSafe",
93+
]
94+
workdir = "/build"
95+
96+
# ── ReScript UI Build Chain ──────────────────────────────────
97+
98+
[layers.deno-toolchain]
99+
description = "Deno runtime for ReScript UI build"
100+
extends = "base"
101+
packages = ["deno"]
102+
cache = true
103+
104+
[layers.ui-build]
105+
description = "Build ReScript frontend assets"
106+
extends = "deno-toolchain"
107+
commands = [
108+
"mkdir -p /build/ui",
109+
"cp -r ui /build/ui",
110+
"cd /build/ui && deno task build",
111+
]
112+
workdir = "/build"
113+
114+
# ── Runtime Image ────────────────────────────────────────────
115+
116+
[layers.runtime]
117+
description = "Minimal production runtime with all compiled artifacts"
118+
from = "cgr.dev/chainguard/wolfi-base:latest"
119+
packages = [
120+
"ca-certificates",
121+
"curl",
122+
"openssl",
123+
"ncurses",
124+
"gtk+3.0",
125+
"webkit2gtk",
126+
"libsoup",
127+
"tesseract-ocr",
128+
"tesseract-ocr-eng",
129+
"espeak-ng",
130+
"hunspell",
131+
"hunspell-en-us",
132+
"pandoc",
133+
]
134+
copy-from = [
135+
{ layer = "rust-build", src = "/build/target/release/formatrix-gui", dst = "/usr/local/bin/formatrix-gui" },
136+
{ layer = "rust-build", src = "/build/target/release/formatrix-core", dst = "/usr/local/lib/libformatrix_core.so" },
137+
{ layer = "ada-build", src = "/build/tui/bin/formatrix-tui", dst = "/usr/local/bin/formatrix-tui" },
138+
{ layer = "zig-build", src = "/build/ffi/zig/zig-out/lib/", dst = "/usr/local/lib/" },
139+
{ layer = "ui-build", src = "/build/ui/dist/", dst = "/opt/formatrix-docs/ui/" },
140+
]
141+
entrypoint = ["/usr/local/bin/formatrix-gui"]
142+
user = "formatrix"
143+
144+
[layers.runtime-tui]
145+
description = "TUI-only runtime (no GUI dependencies)"
146+
from = "cgr.dev/chainguard/wolfi-base:latest"
147+
packages = [
148+
"ca-certificates",
149+
"curl",
150+
"openssl",
151+
"ncurses",
152+
"tesseract-ocr",
153+
"tesseract-ocr-eng",
154+
"hunspell",
155+
"hunspell-en-us",
156+
]
157+
copy-from = [
158+
{ layer = "rust-build", src = "/build/target/release/formatrix-core", dst = "/usr/local/lib/libformatrix_core.so" },
159+
{ layer = "ada-build", src = "/build/tui/bin/formatrix-tui", dst = "/usr/local/bin/formatrix-tui" },
160+
{ layer = "zig-build", src = "/build/ffi/zig/zig-out/lib/", dst = "/usr/local/lib/" },
161+
]
162+
entrypoint = ["/usr/local/bin/formatrix-tui"]
163+
user = "formatrix"
164+
165+
# ── Sidecar: ArangoDB ───────────────────────────────────────
166+
167+
[layers.arangodb]
168+
description = "ArangoDB graph+document database sidecar"
169+
from = "arangodb/arangodb:3.12"
170+
env = { ARANGO_NO_AUTH = "0" }
171+
healthcheck = { test = ["CMD", "curl", "-f", "http://localhost:8529/_api/version"], interval = "30s", timeout = "10s", retries = 5 }
172+
173+
# ── Sidecar: Vosk ───────────────────────────────────────────
174+
175+
[layers.vosk]
176+
description = "Vosk speech-to-text sidecar (optional, profile: speech)"
177+
from = "alphacep/kaldi-vosk-server:latest"
178+
expose = [2700]
179+
180+
# ── Security ───────────────────────────────────────────────────
181+
182+
[security]
183+
non-root = true
184+
read-only-root = true
185+
no-new-privileges = true
186+
cap-drop = ["ALL"]
187+
seccomp-profile = "default"
188+
189+
[security.signing]
190+
algorithm = "ML-DSA-87"
191+
provider = "cerro-torre"
192+
193+
[security.sbom]
194+
format = "spdx-json"
195+
output = "sbom.spdx.json"
196+
include-deps = true
197+
198+
# ── Verification ───────────────────────────────────────────────
199+
200+
[verify]
201+
vordr = true
202+
svalinn = true
203+
scan-on-build = true
204+
fail-on = ["critical", "high"]
205+
206+
# ── Targets ────────────────────────────────────────────────────
207+
208+
[targets.development]
209+
description = "Full dev environment with all toolchains and debug logging"
210+
layers = ["base", "rust-toolchain", "rust-deps", "rust-build", "ada-toolchain", "ada-build", "zig-toolchain", "zig-build", "deno-toolchain", "ui-build"]
211+
env = { LOG_LEVEL = "debug", FORMATRIX_DB_URL = "http://arangodb:8529", FORMATRIX_DB_NAME = "formatrix" }
212+
213+
[targets.production]
214+
description = "Minimal GUI runtime image"
215+
layers = ["runtime"]
216+
env = { LOG_LEVEL = "info", FORMATRIX_DB_URL = "http://arangodb:8529", FORMATRIX_DB_NAME = "formatrix" }
217+
218+
[targets.production-tui]
219+
description = "Minimal TUI-only runtime image (headless / terminal)"
220+
layers = ["runtime-tui"]
221+
env = { LOG_LEVEL = "info", TERM = "xterm-256color", FORMATRIX_DB_URL = "http://arangodb:8529", FORMATRIX_DB_NAME = "formatrix" }
222+
223+
[targets.test]
224+
description = "Build environment for CI test runs"
225+
layers = ["base", "rust-toolchain", "rust-deps", "rust-build", "ada-toolchain", "ada-build", "zig-toolchain", "zig-build", "deno-toolchain", "ui-build"]
226+
env = { LOG_LEVEL = "debug", RUST_BACKTRACE = "1", FORMATRIX_DB_URL = "http://arangodb:8529", FORMATRIX_DB_NAME = "formatrix_test" }
227+
228+
# ── Compose (sidecar orchestration) ──────────────────────────
229+
230+
[compose]
231+
description = "Full stack with ArangoDB and optional Vosk"
232+
233+
[compose.services.formatrix]
234+
target = "production"
235+
ports = []
236+
volumes = [
237+
"formatrix-data:/home/formatrix/.local/share/formatrix-docs",
238+
"${HOME}/Documents:/home/formatrix/Documents:rw",
239+
]
240+
depends-on = ["arangodb"]
241+
network = "formatrix-net"
242+
243+
[compose.services.formatrix-tui]
244+
target = "production-tui"
245+
volumes = [
246+
"formatrix-data:/home/formatrix/.local/share/formatrix-docs",
247+
"${HOME}/Documents:/home/formatrix/Documents:rw",
248+
]
249+
depends-on = ["arangodb"]
250+
network = "formatrix-net"
251+
profiles = ["tui"]
252+
253+
[compose.services.arangodb]
254+
layer = "arangodb"
255+
ports = ["8529:8529"]
256+
volumes = ["arangodb-data:/var/lib/arangodb3", "arangodb-apps:/var/lib/arangodb3-apps"]
257+
network = "formatrix-net"
258+
259+
[compose.services.vosk]
260+
layer = "vosk"
261+
ports = ["2700:2700"]
262+
network = "formatrix-net"
263+
profiles = ["speech"]
264+
265+
[compose.networks.formatrix-net]
266+
driver = "bridge"
267+
268+
[compose.volumes]
269+
formatrix-data = {}
270+
arangodb-data = {}
271+
arangodb-apps = {}

0 commit comments

Comments
 (0)