|
| 1 | +# SPDX-License-Identifier: PMPL-1.0-or-later |
| 2 | +# stapeln.toml — Layer-based container build for palimpsest-license |
| 3 | +# |
| 4 | +# stapeln builds containers as composable layers (German: "to stack"). |
| 5 | +# Each layer is independently cacheable, verifiable, and signable. |
| 6 | + |
| 7 | +[metadata] |
| 8 | +name = "palimpsest-license" |
| 9 | +version = "0.1.0" |
| 10 | +description = "palimpsest-license container service" |
| 11 | +author = "Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>" |
| 12 | +license = "PMPL-1.0-or-later" |
| 13 | +registry = "ghcr.io/hyperpolymath" |
| 14 | + |
| 15 | +[build] |
| 16 | +containerfile = "Containerfile" |
| 17 | +context = "." |
| 18 | +runtime = "podman" |
| 19 | + |
| 20 | +# ── Layer Definitions ────────────────────────────────────────── |
| 21 | + |
| 22 | +[layers.base] |
| 23 | +description = "Chainguard Wolfi minimal base" |
| 24 | +from = "cgr.dev/chainguard/wolfi-base:latest" |
| 25 | +cache = true |
| 26 | +verify = true |
| 27 | + |
| 28 | +[layers.haskell-toolchain] |
| 29 | +description = "GHC and Cabal" |
| 30 | +extends = "base" |
| 31 | +packages = ["ghc", "cabal-install"] |
| 32 | +cache = true |
| 33 | + |
| 34 | +[layers.haskell-deps] |
| 35 | +description = "Cabal dependency fetch" |
| 36 | +extends = "haskell-toolchain" |
| 37 | +commands = ["cabal update", "cabal build --only-dependencies"] |
| 38 | +cache-key = "*.cabal" |
| 39 | +cache = true |
| 40 | + |
| 41 | +[layers.build] |
| 42 | +description = "palimpsest-license Haskell compilation" |
| 43 | +extends = "haskell-deps" |
| 44 | +commands = ["cabal build"] |
| 45 | + |
| 46 | +[layers.runtime] |
| 47 | +description = "Minimal runtime" |
| 48 | +from = "cgr.dev/chainguard/wolfi-base:latest" |
| 49 | +packages = ["ca-certificates", "curl"] |
| 50 | +copy-from = [ |
| 51 | + { layer = "build", src = "/app/", dst = "/app/" }, |
| 52 | +] |
| 53 | +entrypoint = ["["/app/bin/palimpsest-validator", "--help"]"] |
| 54 | +user = "validator:validator" |
| 55 | +expose = [8000] |
| 56 | +env = { LANG = "en_GB.UTF-8", SOURCE_DATE_EPOCH = "1609459200", LC_ALL = "en_GB.UTF-8", NODE_ENV = "production", PYTHONUNBUFFERED = "1" } |
| 57 | + |
| 58 | +# ── Security ─────────────────────────────────────────────────── |
| 59 | + |
| 60 | +[security] |
| 61 | +non-root = true |
| 62 | +read-only-root = false |
| 63 | +no-new-privileges = true |
| 64 | +cap-drop = ["ALL"] |
| 65 | +seccomp-profile = "default" |
| 66 | + |
| 67 | +[security.signing] |
| 68 | +algorithm = "ML-DSA-87" |
| 69 | +provider = "cerro-torre" |
| 70 | + |
| 71 | +[security.sbom] |
| 72 | +format = "spdx-json" |
| 73 | +output = "sbom.spdx.json" |
| 74 | +include-deps = true |
| 75 | + |
| 76 | +# ── Verification ─────────────────────────────────────────────── |
| 77 | + |
| 78 | +[verify] |
| 79 | +vordr = true |
| 80 | +svalinn = true |
| 81 | +scan-on-build = true |
| 82 | +fail-on = ["critical", "high"] |
| 83 | + |
| 84 | +# ── Targets ──────────────────────────────────────────────────── |
| 85 | + |
| 86 | +[targets.development] |
| 87 | +layers = ["base", "haskell-toolchain", "build"] |
| 88 | +env = { LOG_LEVEL = "debug" } |
| 89 | + |
| 90 | +[targets.production] |
| 91 | +layers = ["runtime"] |
| 92 | +env = { LOG_LEVEL = "info" } |
| 93 | + |
| 94 | +[targets.test] |
| 95 | +layers = ["base", "haskell-toolchain", "build"] |
| 96 | +env = { LOG_LEVEL = "debug" } |
0 commit comments