Skip to content

Commit 4981439

Browse files
committed
feat: add stapeln.toml layer-based container definition\n\nConverted from existing Containerfile to stapeln format.\nIncludes Chainguard base, security hardening, SBOM generation.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a4b9537 commit 4981439

1 file changed

Lines changed: 105 additions & 0 deletions

File tree

stapeln.toml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# stapeln.toml — Layer-based container build for http-capability-gateway
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 = "http-capability-gateway"
9+
version = "0.1.0"
10+
description = "http-capability-gateway 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.elixir-toolchain]
29+
description = "Elixir/OTP runtime"
30+
extends = "base"
31+
packages = ["erl27-elixir-1.18", "erlang-27", "git", "build-base"]
32+
cache = true
33+
34+
[layers.elixir-deps]
35+
description = "Mix dependency fetch"
36+
extends = "elixir-toolchain"
37+
env = { MIX_ENV = "prod" }
38+
commands = [
39+
"mix local.hex --force",
40+
"mix local.rebar --force",
41+
"mix deps.get --only prod",
42+
"mix compile",
43+
]
44+
cache-key = "mix.lock"
45+
cache = true
46+
47+
[layers.build]
48+
description = "http-capability-gateway Elixir release"
49+
extends = "elixir-deps"
50+
commands = ["mix release"]
51+
artifacts = [
52+
{ src = "_build/prod/rel/http-capability-gateway", dst = "/app/http-capability-gateway/" },
53+
]
54+
55+
[layers.runtime]
56+
description = "Minimal runtime"
57+
from = "cgr.dev/chainguard/wolfi-base:latest"
58+
packages = ["ca-certificates", "curl"]
59+
copy-from = [
60+
{ layer = "build", src = "/app/", dst = "/app/" },
61+
]
62+
entrypoint = ["["bin/http_capability_gateway", "start"]"]
63+
user = "gateway"
64+
expose = [4000]
65+
env = { MIX_ENV = "prod" }
66+
67+
# ── Security ───────────────────────────────────────────────────
68+
69+
[security]
70+
non-root = true
71+
read-only-root = false
72+
no-new-privileges = true
73+
cap-drop = ["ALL"]
74+
seccomp-profile = "default"
75+
76+
[security.signing]
77+
algorithm = "ML-DSA-87"
78+
provider = "cerro-torre"
79+
80+
[security.sbom]
81+
format = "spdx-json"
82+
output = "sbom.spdx.json"
83+
include-deps = true
84+
85+
# ── Verification ───────────────────────────────────────────────
86+
87+
[verify]
88+
vordr = true
89+
svalinn = true
90+
scan-on-build = true
91+
fail-on = ["critical", "high"]
92+
93+
# ── Targets ────────────────────────────────────────────────────
94+
95+
[targets.development]
96+
layers = ["base", "elixir-toolchain", "build"]
97+
env = { LOG_LEVEL = "debug" }
98+
99+
[targets.production]
100+
layers = ["runtime"]
101+
env = { LOG_LEVEL = "info" }
102+
103+
[targets.test]
104+
layers = ["base", "elixir-toolchain", "build"]
105+
env = { LOG_LEVEL = "debug" }

0 commit comments

Comments
 (0)