springdocker 1.0.3__tar.gz → 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {springdocker-1.0.3/src/springdocker.egg-info → springdocker-1.1.0}/PKG-INFO +223 -24
- springdocker-1.1.0/README.md +305 -0
- springdocker-1.1.0/cli/README.md +381 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/pyproject.toml +24 -4
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/__init__.py +1 -1
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/analyze.py +30 -17
- springdocker-1.1.0/src/springdocker/benchmarks/generate.py +400 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/benchmarks/runner.py +11 -5
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/cli.py +163 -37
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/commands.py +131 -47
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/compare.py +1 -1
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/config.py +301 -21
- springdocker-1.1.0/src/springdocker/config_audit.py +254 -0
- springdocker-1.1.0/src/springdocker/config_serializer.py +135 -0
- springdocker-1.1.0/src/springdocker/configure_wizard.py +193 -0
- springdocker-1.1.0/src/springdocker/digest_pins.py +141 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/dockerfile.py +315 -299
- springdocker-1.1.0/src/springdocker/dockerfile_explain.py +281 -0
- springdocker-1.1.0/src/springdocker/dockerfile_profiles.py +122 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/project_detect.py +173 -17
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/regression.py +33 -21
- springdocker-1.1.0/src/springdocker/runtime_images.py +55 -0
- springdocker-1.1.0/src/springdocker/services/dockerfile_service.py +276 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/services/verify_service.py +56 -0
- {springdocker-1.0.3 → springdocker-1.1.0/src/springdocker.egg-info}/PKG-INFO +223 -24
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker.egg-info/SOURCES.txt +7 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker.egg-info/requires.txt +1 -0
- springdocker-1.0.3/README.md +0 -160
- springdocker-1.0.3/cli/README.md +0 -183
- springdocker-1.0.3/src/springdocker/benchmarks/generate.py +0 -116
- springdocker-1.0.3/src/springdocker/services/dockerfile_service.py +0 -126
- {springdocker-1.0.3 → springdocker-1.1.0}/LICENSE +0 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/setup.cfg +0 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/benchmarks/__init__.py +0 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/errors.py +0 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/plugins.py +0 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/services/__init__.py +0 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/services/benchmark_service.py +0 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/services/project_service.py +0 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/templates/_section.j2 +0 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker/templates/dockerfile.j2 +0 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker.egg-info/dependency_links.txt +0 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker.egg-info/entry_points.txt +0 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/src/springdocker.egg-info/top_level.txt +0 -0
- {springdocker-1.0.3 → springdocker-1.1.0}/tests/test_support.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: springdocker
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: CLI for Spring Boot Dockerfile and benchmark workflows (Maven/Gradle).
|
|
5
5
|
Author: springdocker contributors
|
|
6
6
|
License: Apache License
|
|
@@ -220,6 +220,7 @@ Requires-Dist: pytest>=8.0; extra == "dev"
|
|
|
220
220
|
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
221
221
|
Requires-Dist: ruff>=0.6.0; extra == "dev"
|
|
222
222
|
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
223
|
+
Requires-Dist: types-Jinja2; extra == "dev"
|
|
223
224
|
Requires-Dist: requests>=2.32; extra == "dev"
|
|
224
225
|
Dynamic: license-file
|
|
225
226
|
|
|
@@ -227,19 +228,20 @@ Dynamic: license-file
|
|
|
227
228
|
|
|
228
229
|
CLI for Spring Boot Dockerfile and benchmark workflows across Maven and Gradle projects.
|
|
229
230
|
|
|
231
|
+
Product scope and CI-evidenced guarantees: [`docs/POSITIONING.md`](../docs/POSITIONING.md).
|
|
232
|
+
|
|
230
233
|
## Install
|
|
231
234
|
|
|
232
|
-
|
|
235
|
+
**Primary path:** install from PyPI and run against your Spring Boot project. Clone the repository only for benchmarks on the sample app or for development ([ADR 0006](../docs/adr/0006-pypi-first-distribution.md)).
|
|
233
236
|
|
|
234
|
-
|
|
235
|
-
python3 -m pip install -e .
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### pipx
|
|
237
|
+
### pipx (recommended)
|
|
239
238
|
|
|
240
239
|
```bash
|
|
241
240
|
pipx install springdocker
|
|
242
241
|
springdocker --help
|
|
242
|
+
|
|
243
|
+
# optional: benchmark run/analyze (requires Docker)
|
|
244
|
+
pipx install 'springdocker[benchmark]'
|
|
243
245
|
```
|
|
244
246
|
|
|
245
247
|
Upgrade:
|
|
@@ -254,20 +256,38 @@ pipx upgrade springdocker
|
|
|
254
256
|
uv tool install springdocker
|
|
255
257
|
uv tool upgrade springdocker
|
|
256
258
|
|
|
257
|
-
# benchmark
|
|
258
|
-
|
|
259
|
+
# benchmark extra
|
|
260
|
+
uv tool install 'springdocker[benchmark]'
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### pip
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
python3 -m pip install springdocker
|
|
267
|
+
python3 -m pip install 'springdocker[benchmark]'
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### From source (contributors)
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
git clone https://github.com/mnafshin/springdocker.git
|
|
274
|
+
cd springdocker
|
|
275
|
+
python3 -m pip install -e ".[dev]"
|
|
259
276
|
```
|
|
260
277
|
|
|
261
278
|
## Quick usage
|
|
262
279
|
|
|
263
280
|
```bash
|
|
264
281
|
springdocker init --project-root samples/java-spring-docker --build-tool maven --profile quick
|
|
282
|
+
springdocker configure --project-root samples/java-spring-docker --force # interactive → writes [dockerfile] in config
|
|
283
|
+
springdocker dockerfile generate --project-root samples/java-spring-docker # non-interactive; reads .springdocker.toml
|
|
265
284
|
springdocker doctor --project-root samples/java-spring-docker
|
|
266
285
|
springdocker inspect --project-root samples/java-spring-docker --format json
|
|
267
286
|
springdocker explain --project-root samples/java-spring-docker Dockerfile.generated --format json
|
|
268
287
|
springdocker benchmark compare --project-root samples/java-spring-docker benchmarks/03-custom-jre-jlink/results/raw.csv --baseline-variant with-jlink-runtime --format json
|
|
269
288
|
springdocker dockerfile generate --project-root samples/java-spring-docker --output Dockerfile.generated --recipe jvm-balanced
|
|
270
289
|
springdocker dockerfile generate --project-root samples/java-spring-docker --recipe spring-aot
|
|
290
|
+
# native-aot emits experimental scaffold output only (not a production workflow)
|
|
271
291
|
springdocker dockerfile generate --project-root samples/java-spring-docker --recipe native-aot
|
|
272
292
|
springdocker benchmark generate --project-root samples/java-spring-docker --java-version 25
|
|
273
293
|
springdocker benchmark run --project-root samples/java-spring-docker --profile quick --runner-arg --skip-native
|
|
@@ -278,7 +298,89 @@ springdocker benchmark analyze --project-root samples/java-spring-docker benchma
|
|
|
278
298
|
```
|
|
279
299
|
|
|
280
300
|
Benchmark commands are optional evidence workflows and require benchmark extras.
|
|
281
|
-
Use `samples/java-spring-docker/benchmarks/
|
|
301
|
+
Use `samples/java-spring-docker/benchmarks/06-base-image-choice/results/baseline.json` as the versioned CI regression baseline example (paired with committed `raw.csv`).
|
|
302
|
+
Scenario index: [README.md](../README.md#benchmark-scenario-index).
|
|
303
|
+
|
|
304
|
+
## Dockerfile recipes
|
|
305
|
+
|
|
306
|
+
| Recipe | Status | Default runtime | Notes |
|
|
307
|
+
|---|---|---|---|
|
|
308
|
+
| `jvm-balanced` | Supported | **distroless** + jlink | Default production-oriented JVM Dockerfile. |
|
|
309
|
+
| `spring-aot` | Supported | **distroless** + jlink | Spring Boot AOT processing on a JVM runtime. |
|
|
310
|
+
| `native-aot` | Scaffold only | **distroless** base (static binary) | Experimental GraalVM native-image Dockerfile output. Not a production-ready workflow; see `docs/native-image-roadmap.md`. |
|
|
311
|
+
|
|
312
|
+
The generator sets `runtime_image = "distroless"` internally for JVM recipes. That means `distroless/base-debian*` plus a copied jlink runtime — not the prebuilt `distroless/java*` image and not a full OS layer unless you change generator options (benchmark scenario **06** compares OS bases).
|
|
313
|
+
|
|
314
|
+
### Runtime bases and HEALTHCHECK
|
|
315
|
+
|
|
316
|
+
| Runtime | Generator behavior |
|
|
317
|
+
|---|---|
|
|
318
|
+
| `distroless` (default) | Non-root, minimal base + jlink; **no `HEALTHCHECK`** (no shell/`wget` in the image). Probe readiness from the orchestrator (e.g. Kubernetes `readinessProbe` on `/actuator/health/readiness`). |
|
|
319
|
+
| `debian-slim`, `alpine`, `ubuntu`, `temurin` | Full OS or vendor JRE paths; **`HEALTHCHECK` is emitted** when Spring Boot Actuator is on the classpath. |
|
|
320
|
+
|
|
321
|
+
Supported runtime names: `distroless`, `debian-slim`, `alpine`, `ubuntu`, `temurin` (plus aliases such as `debian-bookworm-slim`, `eclipse-temurin-jre`). Set via `[dockerfile].runtime_image` in `.springdocker.toml` or `--runtime-image` on `dockerfile generate`.
|
|
322
|
+
|
|
323
|
+
## Config-first workflow
|
|
324
|
+
|
|
325
|
+
`.springdocker.toml` is the **single source of truth** for Dockerfile generation (see [ADR 0005](../docs/adr/0005-config-first-dockerfile-generation.md)). Team rollout guide: [docs/team-adoption.md](../docs/team-adoption.md).
|
|
326
|
+
|
|
327
|
+
### Command matrix
|
|
328
|
+
|
|
329
|
+
| Command | Interactive? | Writes config? | Writes Dockerfile? | Typical user |
|
|
330
|
+
|---|---|---|---|---|
|
|
331
|
+
| `springdocker init` | No | Yes (skeleton) | No | Platform / first checkout |
|
|
332
|
+
| `springdocker init --interactive` | Yes (via configure) | Yes | No | New service bootstrap |
|
|
333
|
+
| `springdocker configure` | Yes | Yes (`[dockerfile]`) | Optional (`--generate`) | Strategy changes |
|
|
334
|
+
| `springdocker dockerfile generate` | No | No | Yes | Daily dev + CI |
|
|
335
|
+
| `springdocker explain --config-aware` | No | No | No | Audit / review (advisory — not a CI gate) |
|
|
336
|
+
| `springdocker verify --check-config-drift` | No | No | No | CI SSOT gate (pass/fail) |
|
|
337
|
+
|
|
338
|
+
### Precedence
|
|
339
|
+
|
|
340
|
+
| Priority | Source |
|
|
341
|
+
|---:|---|
|
|
342
|
+
| 1 | CLI flags on `dockerfile generate` |
|
|
343
|
+
| 2 | Project `.springdocker.toml` |
|
|
344
|
+
| 3 | Built-in defaults |
|
|
345
|
+
|
|
346
|
+
Org policy (`SPRINGDOCKER_POLICY`) is planned ([#123](https://github.com/mnafshin/springdocker/issues/123)); not required today.
|
|
347
|
+
|
|
348
|
+
| Command | Purpose |
|
|
349
|
+
|---|---|
|
|
350
|
+
| `springdocker configure` | Interactive wizard that writes/updates `[dockerfile]` in config |
|
|
351
|
+
| `springdocker init --interactive` | Create config skeleton, then run configure |
|
|
352
|
+
| `springdocker dockerfile generate` | Deterministic generate from config (CI-safe, no prompts) |
|
|
353
|
+
|
|
354
|
+
Profiles (`production-balanced`, `smallest-image`, `fast-cold-start`, `build-speed`, `simplest`, `compliance`, `custom`) are selected in `configure` and expanded to explicit options in config.
|
|
355
|
+
|
|
356
|
+
### `dockerfile generate` CLI overrides
|
|
357
|
+
|
|
358
|
+
Every `[dockerfile]` key is overridable from the CLI except file-backed keys (`must_have_modules_file`, `jlink_baseline_modules`), which stay in config only.
|
|
359
|
+
|
|
360
|
+
| Section | CLI flags | Config key(s) |
|
|
361
|
+
|---|---|---|
|
|
362
|
+
| General | `--output`, `--java-version`, `--recipe`, `--profile` | `output`, `java_version`, `recipe`, `profile` |
|
|
363
|
+
| Runtime | `--runtime-image`, `--non-root` / `--no-non-root`, `--platform-aware` / `--no-platform-aware`, `--healthcheck-path` | `runtime_image`, `non_root`, `platform_aware`, `healthcheck_path` |
|
|
364
|
+
| Build | `--use-buildkit-cache` / `--no-use-buildkit-cache`, `--use-jlink` / `--no-use-jlink`, `--use-layered-jar` / `--no-use-layered-jar` | `use_buildkit_cache`, `use_jlink`, `use_layered_jar` |
|
|
365
|
+
| Supply chain | `--include-oci-labels`, `--include-stopsignal`, `--include-embedded-sbom`, `--include-reproducible-controls`, `--pin-digests` (each with `--no-*` form) | matching `include_*` keys and `pin_digests` |
|
|
366
|
+
| JVM | `--enable-appcds`, `--enable-jep483-aot-cache`, `--tuned-jvm-flags`, `--jvm-flag` (repeatable) | `enable_appcds`, `enable_jep483_aot_cache`, `tuned_jvm_flags`, `jvm_flags` |
|
|
367
|
+
|
|
368
|
+
Example one-off CI override:
|
|
369
|
+
|
|
370
|
+
```bash
|
|
371
|
+
springdocker dockerfile generate \
|
|
372
|
+
--project-root samples/java-spring-docker \
|
|
373
|
+
--runtime-image alpine \
|
|
374
|
+
--no-use-jlink \
|
|
375
|
+
--enable-jep483-aot-cache \
|
|
376
|
+
--no-include-embedded-sbom \
|
|
377
|
+
--pin-digests \
|
|
378
|
+
--jvm-flag "-XX:+UseZGC" # or --jvm-flag=-XX:+UseZGC when the flag starts with '-'
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
The `dockerfile generate` `--help` output groups flags under **runtime**, **build**, **supply chain**, and **JVM** sections.
|
|
382
|
+
|
|
383
|
+
The `07-native-benchmark` scenario is generated with the `native-aot` scaffold recipe. The internal benchmark runner skips native scenarios by default (`--skip-native`).
|
|
282
384
|
|
|
283
385
|
## Config file (`.springdocker.toml`)
|
|
284
386
|
|
|
@@ -301,9 +403,16 @@ build_tool = "maven"
|
|
|
301
403
|
output = "Dockerfile.generated"
|
|
302
404
|
java_version = 25
|
|
303
405
|
recipe = "jvm-balanced"
|
|
406
|
+
# profile = "production-balanced" # set by `springdocker configure`
|
|
407
|
+
# runtime_image = "distroless"
|
|
408
|
+
# use_jlink = true
|
|
409
|
+
# enable_jep483_aot_cache = false
|
|
410
|
+
# include_embedded_sbom = true
|
|
411
|
+
# pin_digests = true
|
|
412
|
+
# tuned_jvm_flags = true
|
|
413
|
+
# jvm_flags = ["-XX:MaxRAMPercentage=75", "-XX:+ExitOnOutOfMemoryError", "-Djava.io.tmpdir=/tmp"]
|
|
414
|
+
# Generator default runtime: distroless (gcr.io/distroless/base-* + jlink + layered JAR).
|
|
304
415
|
must_have_modules_file = "must-have.txt"
|
|
305
|
-
legacy_scripts = false
|
|
306
|
-
wizard_args = []
|
|
307
416
|
|
|
308
417
|
[benchmark.generate]
|
|
309
418
|
java_version = 25
|
|
@@ -324,6 +433,28 @@ When `dockerfile.must_have_modules_file` is set, springdocker reads modules from
|
|
|
324
433
|
(`must-have.txt` style, one module per line, `#` comments allowed) and injects them into
|
|
325
434
|
the jlink module list for reflection/dynamic-loading edge cases.
|
|
326
435
|
|
|
436
|
+
When jlink is enabled, springdocker auto-merges **jlink baseline modules** when Spring Web starters
|
|
437
|
+
are detected (`spring-boot-starter-web`, `spring-boot-starter-webflux`, `spring-boot-starter-websocket`):
|
|
438
|
+
|
|
439
|
+
- `java.desktop` — JavaBeans and desktop-related APIs used by parts of the Spring Web stack
|
|
440
|
+
- `java.logging` — `java.util.logging` used by framework and library code
|
|
441
|
+
- `java.naming` — JNDI lookups that jdeps often misses on web apps
|
|
442
|
+
|
|
443
|
+
Non-web Spring Boot workloads get **no** auto baseline — use jdeps plus `must_have_modules_file` for
|
|
444
|
+
extra modules. Override or disable in `.springdocker.toml`:
|
|
445
|
+
|
|
446
|
+
```toml
|
|
447
|
+
[dockerfile]
|
|
448
|
+
# Omit jlink_baseline_modules to auto-detect from Spring Web starters at generate time.
|
|
449
|
+
# Override defaults or set [] to disable baseline injection.
|
|
450
|
+
jlink_baseline_modules = ["java.desktop", "java.logging", "java.naming"]
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
See [ADR 0007](../docs/adr/0007-jlink-baseline-modules-web-detection.md).
|
|
454
|
+
|
|
455
|
+
`springdocker explain` reports baseline and curated modules separately in JSON/table output.
|
|
456
|
+
Baseline modules are generator defaults; curated modules come from `must_have_modules_file`.
|
|
457
|
+
|
|
327
458
|
Create template config:
|
|
328
459
|
|
|
329
460
|
```bash
|
|
@@ -331,24 +462,32 @@ springdocker init --project-root samples/java-spring-docker --build-tool gradle
|
|
|
331
462
|
springdocker init --project-root samples/java-spring-docker --build-tool gradle --profile full --print
|
|
332
463
|
```
|
|
333
464
|
|
|
334
|
-
|
|
465
|
+
### `init --interactive`
|
|
335
466
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
To force script wrappers for compatibility:
|
|
467
|
+
Creates `.springdocker.toml` if missing, then runs the same wizard as `configure` (no Dockerfile write unless you chain commands yourself):
|
|
339
468
|
|
|
340
469
|
```bash
|
|
341
|
-
springdocker
|
|
342
|
-
|
|
343
|
-
springdocker
|
|
470
|
+
springdocker init --project-root . --build-tool maven --interactive
|
|
471
|
+
# equivalent to:
|
|
472
|
+
# springdocker init --project-root . --build-tool maven
|
|
473
|
+
# springdocker configure --project-root . --force
|
|
344
474
|
```
|
|
345
475
|
|
|
346
|
-
|
|
476
|
+
Use `--force` on `init` to overwrite an existing skeleton; use `configure --force` to replace only the `[dockerfile]` section in an existing file.
|
|
477
|
+
|
|
478
|
+
See [docs/team-adoption.md](../docs/team-adoption.md) for first-time setup, CI examples, and migration from the retired `tools/dockerfile_wizard.py`.
|
|
479
|
+
|
|
480
|
+
## Legacy benchmark scripts
|
|
481
|
+
|
|
482
|
+
Benchmark commands still support `--use-legacy-scripts` (or `SPRINGDOCKER_LEGACY_SCRIPTS=1`) to delegate to project scripts under `benchmarks/` when needed:
|
|
347
483
|
|
|
348
484
|
```bash
|
|
349
|
-
|
|
485
|
+
springdocker benchmark generate --use-legacy-scripts ...
|
|
486
|
+
springdocker benchmark run --use-legacy-scripts ...
|
|
350
487
|
```
|
|
351
488
|
|
|
489
|
+
Dockerfile generation always uses the internal config-driven generator. Use `springdocker configure` for interactive setup instead of the retired `tools/dockerfile_wizard.py` script.
|
|
490
|
+
|
|
352
491
|
## Inspect command
|
|
353
492
|
|
|
354
493
|
`springdocker inspect` prints static metadata about the target project:
|
|
@@ -364,16 +503,76 @@ Use `--format json` for machine-readable output.
|
|
|
364
503
|
|
|
365
504
|
## Explain command
|
|
366
505
|
|
|
367
|
-
`springdocker explain` reads a
|
|
506
|
+
`springdocker explain` reads a Dockerfile and **describes** optimizations it recognizes using static text heuristics (regex and keyword matching).
|
|
507
|
+
|
|
508
|
+
**Advisory only — not a CI gate.** Explain output helps humans review and document a Dockerfile. It does **not** perform a security audit, lint the file, scan images, or prove runtime correctness. Hand-written Dockerfiles may be misread; a missing feature in explain output does not mean that optimization is absent at runtime.
|
|
509
|
+
|
|
510
|
+
**Use `springdocker verify` for CI gates** — hadolint, trivy, SBOM checks, optional dive/cosign/smoke, and `--check-config-drift` for config SSOT compliance. Only `verify` uses pass/fail semantics suitable for blocking merges.
|
|
511
|
+
|
|
512
|
+
Recognized signals include:
|
|
368
513
|
|
|
369
514
|
- multi-stage layout
|
|
370
515
|
- BuildKit cache usage
|
|
371
516
|
- jlink runtime stage
|
|
372
517
|
- non-root runtime
|
|
373
518
|
- tuned JVM flags
|
|
374
|
-
-
|
|
519
|
+
- jlink baseline modules (built-in defaults)
|
|
520
|
+
- curated must-have modules (from `must-have.txt`)
|
|
521
|
+
|
|
522
|
+
Use `--format json` when you want stable structured output. The JSON `notes` field repeats the advisory scope and points to `verify`.
|
|
523
|
+
|
|
524
|
+
Add `--config-aware` to include resolved `[dockerfile]` options from `.springdocker.toml`, per-option sources (`default` or `project`), and drift detection against `dockerfile generate`. Config drift in explain is informational; enforce SSOT in CI with `verify --check-config-drift`:
|
|
525
|
+
|
|
526
|
+
```bash
|
|
527
|
+
springdocker explain --project-root . Dockerfile.generated --format json --config-aware
|
|
528
|
+
springdocker verify --project-root . --dockerfile Dockerfile.generated --check-config-drift
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
## Verify command
|
|
532
|
+
|
|
533
|
+
`springdocker verify` runs a battery of checks against a generated Dockerfile and optional runtime context. It is designed to work in CI without installing every external tool.
|
|
534
|
+
|
|
535
|
+
```bash
|
|
536
|
+
springdocker verify --project-root tests/fixtures/maven-only Dockerfile.generated
|
|
537
|
+
springdocker verify --project-root tests/fixtures/maven-only Dockerfile.generated \
|
|
538
|
+
--image demo:latest \
|
|
539
|
+
--smoke-url http://127.0.0.1:8081/actuator/health \
|
|
540
|
+
--format junit \
|
|
541
|
+
--output reports/verify.junit.xml
|
|
542
|
+
springdocker verify --project-root . --dockerfile Dockerfile.generated --check-config-drift
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
`--check-config-drift` adds config SSOT checks when `.springdocker.toml` is present:
|
|
546
|
+
|
|
547
|
+
| Check | Validates |
|
|
548
|
+
|---|---|
|
|
549
|
+
| `config-drift` | Dockerfile matches `dockerfile generate` output for current config |
|
|
550
|
+
| `config-embedded-sbom` | `/usr/share/sbom/spdx.json` present when `include_embedded_sbom = true` |
|
|
551
|
+
| `config-non-root` | unprivileged `USER` when `non_root = true` |
|
|
552
|
+
| `config-jvm-flags` | configured JVM flags appear in `ENTRYPOINT` |
|
|
553
|
+
|
|
554
|
+
### Built-in checks
|
|
555
|
+
|
|
556
|
+
| Check | Requires | Missing prerequisite | Check failure |
|
|
557
|
+
|---|---|---|---|
|
|
558
|
+
| `hadolint` | `hadolint` on `PATH` | **skipped** (`hadolint not installed`) | non-zero exit |
|
|
559
|
+
| `trivy` | `trivy` on `PATH` | **skipped** (`trivy not installed`) | HIGH/CRITICAL findings |
|
|
560
|
+
| `dive` | `--image` and `dive` on `PATH` | **skipped** (`no image provided` or `dive not installed`) | non-zero exit |
|
|
561
|
+
| `cosign` | `--image` and `cosign` on `PATH` | **skipped** (`no image provided` or `cosign not installed`) | non-zero exit |
|
|
562
|
+
| `sbom` | `sbom.spdx.json` in project root | n/a (always runs) | **failed** if file missing, invalid JSON, or missing `spdxVersion` |
|
|
563
|
+
| `smoke` | `--smoke-url` | **skipped** (`no smoke URL provided`) | HTTP/network error or status ≥ 400 |
|
|
564
|
+
|
|
565
|
+
Verifier plugins registered under `springdocker.verifiers` run after the built-in checks. See `docs/extensions.md`.
|
|
566
|
+
|
|
567
|
+
### Skip vs fail semantics
|
|
568
|
+
|
|
569
|
+
- **skipped** checks do not fail the command. They appear in table/JSON/JUnit/SARIF output for visibility.
|
|
570
|
+
- **failed** checks set the overall result to `failed` and make `springdocker verify` exit with code `1`.
|
|
571
|
+
- Only **failed** checks affect the exit code. A run where every external tool is missing but `sbom.spdx.json` is valid still exits `0`.
|
|
572
|
+
|
|
573
|
+
Optional tools are intentionally optional: install `hadolint`, `trivy`, `dive`, and `cosign` locally or in CI when you want those gates enforced.
|
|
375
574
|
|
|
376
|
-
|
|
575
|
+
Supported `--format` values: `table` (default), `json`, `junit`, `sarif`, plus plugin-provided formats.
|
|
377
576
|
|
|
378
577
|
## Security hardening
|
|
379
578
|
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
# springdocker
|
|
2
|
+
|
|
3
|
+
[](https://github.com/mnafshin/springdocker/actions/workflows/ci.yml)
|
|
4
|
+
[](https://github.com/mnafshin/springdocker/actions/workflows/release.yml)
|
|
5
|
+
[](https://github.com/astral-sh/ruff)
|
|
6
|
+
[](./CONTRIBUTING.md#coverage-policy)
|
|
7
|
+
[](./docs/benchmark-methodology.md)
|
|
8
|
+
|
|
9
|
+
Developer toolkit for **production teams** containerizing Spring Boot — with optional benchmark evidence for tuning and conference demos.
|
|
10
|
+
|
|
11
|
+
`springdocker` is a Python CLI that helps teams inspect a Spring Boot project, commit Dockerfile strategy in `.springdocker.toml`, generate and verify Dockerfiles in CI, and (optionally) run benchmark suites for evidence-backed tuning.
|
|
12
|
+
|
|
13
|
+
See [`docs/POSITIONING.md`](docs/POSITIONING.md) for **who it is for**, CI-evidenced guarantees, and how the sample projects relate to shipped behavior.
|
|
14
|
+
|
|
15
|
+
## Who it's for
|
|
16
|
+
|
|
17
|
+
Resolved in [#87](https://github.com/mnafshin/springdocker/issues/87) — see [`docs/adr/0008-target-audience.md`](docs/adr/0008-target-audience.md).
|
|
18
|
+
|
|
19
|
+
| Audience | Fit |
|
|
20
|
+
|---|---|
|
|
21
|
+
| **Production teams** (primary) | Adopt via PyPI on **your** Maven/Gradle service — config-first Dockerfile workflow, explain/verify in CI, Java **17+** on your project |
|
|
22
|
+
| **Conference / storytelling** (secondary) | Clone for presentations and benchmark evidence under `samples/java-spring-docker/` — numbers are sample-specific, not universal guarantees |
|
|
23
|
+
| **Personal lab only** (not primary) | Bleeding-edge sample (Boot 4 / Java 25) stress-tests the generator inside the repo; you do not need to match those versions to use the CLI |
|
|
24
|
+
|
|
25
|
+
**Not** a black-box image builder like Jib or Buildpacks — you own the Dockerfile. **Not** a research-only toy — CI gates the installable CLI; benchmarks and decks are optional depth.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
**Primary path: PyPI** — install the CLI and run it on your Spring Boot project. You do not need to clone this repository for Dockerfile generation, explain, or verify.
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Recommended: isolated user install (Dockerfile workflow)
|
|
33
|
+
pipx install springdocker
|
|
34
|
+
# or
|
|
35
|
+
uv tool install springdocker
|
|
36
|
+
|
|
37
|
+
# Include benchmark run/analyze (optional; requires Docker on the host)
|
|
38
|
+
pipx install 'springdocker[benchmark]'
|
|
39
|
+
# or: python3 -m pip install 'springdocker[benchmark]' inside your project venv
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
See [`cli/README.md`](cli/README.md#install) for pip/editable options and upgrade commands.
|
|
43
|
+
|
|
44
|
+
### When to clone this repository
|
|
45
|
+
|
|
46
|
+
| Goal | What to do |
|
|
47
|
+
|---|---|
|
|
48
|
+
| Generate/explain/verify Dockerfiles for **your** service | Install from PyPI only |
|
|
49
|
+
| Reproduce benchmark evidence, presentations, or pinned CI baselines | Clone; work under `samples/java-spring-docker/` — see [`docs/presentation/README.md`](docs/presentation/README.md) for deck ownership and update policy |
|
|
50
|
+
| Contribute to the CLI | Clone; editable install — see [Contributing](#contributing) |
|
|
51
|
+
|
|
52
|
+
Resolved in [#97](https://github.com/mnafshin/springdocker/issues/97) — see [`docs/adr/0006-pypi-first-distribution.md`](docs/adr/0006-pypi-first-distribution.md).
|
|
53
|
+
|
|
54
|
+
## Project naming
|
|
55
|
+
|
|
56
|
+
**springdocker** is the canonical name for this project — use it when searching GitHub or PyPI, installing the package, or running the CLI.
|
|
57
|
+
|
|
58
|
+
| Surface | Name |
|
|
59
|
+
|---|---|
|
|
60
|
+
| GitHub repository | [`mnafshin/springdocker`](https://github.com/mnafshin/springdocker) |
|
|
61
|
+
| PyPI package / `pip install` | `springdocker` |
|
|
62
|
+
| CLI command | `springdocker` |
|
|
63
|
+
| Config file | `.springdocker.toml` |
|
|
64
|
+
|
|
65
|
+
The string **`java-spring-docker`** appears only in the benchmark sample app, not in the CLI package:
|
|
66
|
+
|
|
67
|
+
| Surface | Path or coordinates | Role |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| Sample app directory | `samples/java-spring-docker/` | Full Spring Boot app for benchmark scenarios and evidence |
|
|
70
|
+
| Sample Maven/Gradle artifact | `io.github.mnafshin:java-spring-docker` | Demo application identity inside that sample |
|
|
71
|
+
|
|
72
|
+
Those sample names predate the **springdocker** product name. They do not affect installation (`pip install springdocker`) or CLI usage. Your local clone directory can be named anything.
|
|
73
|
+
|
|
74
|
+
## Why springdocker instead of Jib or Buildpacks?
|
|
75
|
+
|
|
76
|
+
- **Jib** and **Buildpacks** optimize for build convenience and opaque image assembly.
|
|
77
|
+
- **springdocker** optimizes for teams that want a **real Dockerfile they can own, read, and edit**.
|
|
78
|
+
- It combines explicit Dockerfile generation with explainability and verification workflows.
|
|
79
|
+
- **`explain`** is advisory static analysis for human review; **`verify`** is the pass/fail command for CI gates.
|
|
80
|
+
|
|
81
|
+
See [`docs/POSITIONING.md`](docs/POSITIONING.md) for the detailed comparison and tradeoffs.
|
|
82
|
+
|
|
83
|
+
## Architecture
|
|
84
|
+
|
|
85
|
+
```mermaid
|
|
86
|
+
flowchart LR
|
|
87
|
+
dev[Developer] --> cli[springdocker CLI]
|
|
88
|
+
cli --> cfg[.springdocker.toml]
|
|
89
|
+
cli --> proj[Spring Boot project]
|
|
90
|
+
cli --> df[Generated Dockerfile]
|
|
91
|
+
cli --> bench[Benchmark variants + raw CSV]
|
|
92
|
+
bench --> report[Table / JSON analysis]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
See `docs/architecture.md` for the detailed module map and command lifecycle.
|
|
96
|
+
|
|
97
|
+
The repo is split into these main surfaces:
|
|
98
|
+
|
|
99
|
+
- `src/springdocker/` - installable CLI package and core implementation.
|
|
100
|
+
- `cli/README.md` - command reference and configuration details.
|
|
101
|
+
|
|
102
|
+
See [Sample project map](#sample-project-map) for which Spring Boot path to use.
|
|
103
|
+
|
|
104
|
+
## What it does
|
|
105
|
+
|
|
106
|
+
**Shipped and CI-validated:** project detection, config, Dockerfile generation, explain/verify commands, and benchmark asset/analyzer plumbing (see [`docs/POSITIONING.md`](docs/POSITIONING.md#shipped-guarantees-ci-evidenced)).
|
|
107
|
+
|
|
108
|
+
**Optional / sample-anchored:** full benchmark runs, performance comparison tables, and reference evidence under `samples/java-spring-docker/`.
|
|
109
|
+
|
|
110
|
+
- Detects Maven or Gradle projects.
|
|
111
|
+
- Writes a starter `.springdocker.toml` config.
|
|
112
|
+
- Generates Dockerfiles with opinionated Spring Boot defaults (`jvm-balanced`: **distroless** runtime + custom **jlink** runtime + layered JAR).
|
|
113
|
+
- Pins generated base images by digest when known.
|
|
114
|
+
- Creates benchmark variants and runs benchmark suites (requires Docker and `[benchmark]` extra).
|
|
115
|
+
- Summarizes benchmark CSV output as a table or JSON.
|
|
116
|
+
|
|
117
|
+
Digest pins are centralized in `src/springdocker/digest_pins.py` and verified in CI.
|
|
118
|
+
Runbook: [`docs/digest-pin-runbook.md`](docs/digest-pin-runbook.md) · Renovate template: [`.github/renovate.json`](.github/renovate.json)
|
|
119
|
+
|
|
120
|
+
## Sample project map
|
|
121
|
+
|
|
122
|
+
| Path | Role | Use when |
|
|
123
|
+
|---|---|---|
|
|
124
|
+
| `tests/fixtures/{maven-only,gradle-only}/` | Minimal Spring Boot apps for CLI walkthroughs and CI | Learning the CLI, trying Dockerfile generation, or extending tests ([`docs/golden-samples.md`](docs/golden-samples.md)) |
|
|
125
|
+
| `samples/java-spring-docker/` | Benchmark harness + evidence | Running benchmark scenarios and comparing `raw.csv` results |
|
|
126
|
+
|
|
127
|
+
Gradle walkthroughs use `tests/fixtures/gradle-only/` with the same commands below (Maven: `tests/fixtures/maven-only/`).
|
|
128
|
+
|
|
129
|
+
See [`docs/adr/0004-sample-project-strategy.md`](docs/adr/0004-sample-project-strategy.md) for why the former `examples/` walkthrough tree was removed.
|
|
130
|
+
|
|
131
|
+
## Quick start
|
|
132
|
+
|
|
133
|
+
Install from PyPI first (see [Install](#install)). Then run against **your** Spring Boot project:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
cd /path/to/your-spring-boot-app
|
|
137
|
+
springdocker doctor --project-root .
|
|
138
|
+
springdocker init --project-root . --build-tool maven
|
|
139
|
+
springdocker configure --project-root . --force
|
|
140
|
+
springdocker dockerfile generate --project-root .
|
|
141
|
+
springdocker explain --project-root . Dockerfile.generated --config-aware # advisory review
|
|
142
|
+
springdocker verify --project-root . Dockerfile.generated --check-config-drift # CI gate
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
To try the CLI without your own app, clone this repo and use the minimal fixtures (see [Sample project map](#sample-project-map)):
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
git clone https://github.com/mnafshin/springdocker.git
|
|
149
|
+
cd springdocker
|
|
150
|
+
pipx install 'springdocker[benchmark]' # or: pip install -e '.[dev]' for contributing
|
|
151
|
+
|
|
152
|
+
springdocker doctor --project-root tests/fixtures/maven-only
|
|
153
|
+
springdocker init --project-root tests/fixtures/maven-only --build-tool maven
|
|
154
|
+
springdocker configure --project-root tests/fixtures/maven-only --force
|
|
155
|
+
springdocker dockerfile generate --project-root tests/fixtures/maven-only
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Benchmark workflow** (optional; requires clone + Docker + `[benchmark]` extra) — use the full sample app under `samples/`:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
cd springdocker # repository root after clone
|
|
162
|
+
springdocker benchmark generate --project-root samples/java-spring-docker --java-version 25
|
|
163
|
+
springdocker benchmark run --project-root samples/java-spring-docker --profile quick
|
|
164
|
+
springdocker benchmark analyze --project-root samples/java-spring-docker samples/java-spring-docker/benchmarks/03-custom-jre-jlink/results/raw.csv --format table
|
|
165
|
+
springdocker benchmark compare --project-root samples/java-spring-docker samples/java-spring-docker/benchmarks/03-custom-jre-jlink/results/raw.csv --baseline-variant with-jlink-runtime
|
|
166
|
+
springdocker benchmark analyze --project-root samples/java-spring-docker samples/java-spring-docker/benchmarks/06-base-image-choice/results/raw.csv --baseline samples/java-spring-docker/benchmarks/06-base-image-choice/results/baseline.json
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Default runtime:** `dockerfile generate` with `--recipe jvm-balanced` (the default) uses **`runtime_image = distroless`**: a digest-pinned `gcr.io/distroless/base-*:nonroot` stage plus a jlink-built JVM and layered Spring Boot JAR — not a full OS image. Distroless images have no shell, so generated Dockerfiles **omit `HEALTHCHECK`**; configure readiness probes in Kubernetes or your orchestrator. OS runtime bases are compared in benchmark scenario **06** — see [`cli/README.md`](cli/README.md#dockerfile-recipes).
|
|
170
|
+
|
|
171
|
+
## CLI workflow
|
|
172
|
+
|
|
173
|
+
1. `doctor` checks the project root and build tool.
|
|
174
|
+
2. `init` writes a starter config file.
|
|
175
|
+
3. `dockerfile generate` writes a Dockerfile to the requested path (default recipe: distroless + jlink layered JAR).
|
|
176
|
+
4. `benchmark generate` creates benchmark scenarios.
|
|
177
|
+
5. `benchmark run` executes the benchmark runner.
|
|
178
|
+
6. `benchmark analyze` turns `raw.csv` into a table or JSON summary.
|
|
179
|
+
|
|
180
|
+
See `cli/README.md` for the command reference and config precedence rules.
|
|
181
|
+
|
|
182
|
+
## Benchmark methodology
|
|
183
|
+
|
|
184
|
+
See `docs/benchmark-methodology.md` for the benchmark model, run profiles, and summary calculations.
|
|
185
|
+
|
|
186
|
+
Benchmarks are an optional evidence subsystem and require benchmark extras (`springdocker[benchmark]`).
|
|
187
|
+
|
|
188
|
+
The sample project keeps benchmark scenarios under `samples/java-spring-docker/benchmarks/`.
|
|
189
|
+
Generated variant Dockerfiles and most run output are **gitignored** — regenerate with `springdocker benchmark generate` and `springdocker benchmark run`.
|
|
190
|
+
The scenario 06 CI regression baseline lives under `samples/java-spring-docker/benchmarks/06-base-image-choice/results/`.
|
|
191
|
+
See `samples/java-spring-docker/benchmarks/README.md` for the full artifact policy.
|
|
192
|
+
|
|
193
|
+
### Benchmark scenario index
|
|
194
|
+
|
|
195
|
+
Authoritative list of generated scenarios under `samples/java-spring-docker/benchmarks/`.
|
|
196
|
+
Regenerate directories with `springdocker benchmark generate`. Scenario **07** is listed after **06** and before **08** by id, even though the generator emits **08** before the native scaffold.
|
|
197
|
+
|
|
198
|
+
| ID | Directory | Purpose | Variants | Further reading |
|
|
199
|
+
|---|---|---|---|---|
|
|
200
|
+
| 01 | `01-multi-stage-build-structure` | Multi-stage Dockerfile layout vs a simpler two-stage build | `specialized-multi-stage`, `simple-two-stage` | [`benchmark-methodology.md`](docs/benchmark-methodology.md#current-sample-comparison-snapshot) |
|
|
201
|
+
| 02 | `02-buildkit-gradle-cache` | BuildKit cache mount on dependency rebuilds | `with-buildkit-cache`, `without-buildkit-cache` | [`benchmark-methodology.md`](docs/benchmark-methodology.md#current-sample-comparison-snapshot) |
|
|
202
|
+
| 03 | `03-custom-jre-jlink` | jlink vs vendor JRE on debian-slim vs stock Temurin image | `with-jlink-runtime`, `without-jlink-runtime`, `temurin-jre-image` | [`jvm-optimization.md`](docs/jvm-optimization.md), [`golden-samples.md`](docs/golden-samples.md) |
|
|
203
|
+
| 04 | `04-jep483-aot-cache` | JEP 483 ahead-of-time class-loading cache (Java 24+) | `with-aot-cache`, `without-aot-cache` | [`jvm-optimization.md`](docs/jvm-optimization.md) · extra runs: 8 (`quick`) / 15 (`full`) |
|
|
204
|
+
| 05 | `05-jvm-container-flags` | Tuned vs baseline JVM container flags | `tuned-flags`, `defaults-like` | [`jvm-optimization.md`](docs/jvm-optimization.md) |
|
|
205
|
+
| 06 | `06-base-image-choice` | Runtime base image tradeoffs (jlink on every base) | `alpine`, `debian-slim`, `ubuntu`, `distroless` (configurable) | [`benchmark-methodology.md`](docs/benchmark-methodology.md#configuring-base-image-variants-scenario-06) · CI regression baseline |
|
|
206
|
+
| 07 | `07-native-benchmark` | Native-image scaffold (`native-aot` recipe); skipped by default | _(single Dockerfile at scenario root — no variant dirs)_ | [`native-image-roadmap.md`](docs/native-image-roadmap.md) |
|
|
207
|
+
| 08 | `08-appcds` | AppCDS shared archive at build time | `with-appcds`, `without-appcds` | [`jvm-optimization.md`](docs/jvm-optimization.md) |
|
|
208
|
+
|
|
209
|
+
Example analyze commands (after `benchmark run`):
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
springdocker benchmark analyze --project-root samples/java-spring-docker \
|
|
213
|
+
benchmarks/03-custom-jre-jlink/results/raw.csv --format table
|
|
214
|
+
springdocker benchmark analyze --project-root samples/java-spring-docker \
|
|
215
|
+
benchmarks/04-jep483-aot-cache/results/raw.csv --format json
|
|
216
|
+
springdocker benchmark compare --project-root samples/java-spring-docker \
|
|
217
|
+
benchmarks/03-custom-jre-jlink/results/raw.csv --baseline-variant with-jlink-runtime
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Current reports focus on:
|
|
221
|
+
|
|
222
|
+
- image size
|
|
223
|
+
- build duration
|
|
224
|
+
- startup latency
|
|
225
|
+
- success rate
|
|
226
|
+
|
|
227
|
+
Benchmark summaries can be rendered as:
|
|
228
|
+
|
|
229
|
+
- terminal tables
|
|
230
|
+
- JSON
|
|
231
|
+
|
|
232
|
+
## Supported stack
|
|
233
|
+
|
|
234
|
+
| Layer | CI / fixtures | Reference sample (`samples/java-spring-docker/`) |
|
|
235
|
+
|---|---|---|
|
|
236
|
+
| Python CLI | 3.10–3.12 tested in CI | — |
|
|
237
|
+
| Build tools | Maven and Gradle (minimal fixtures + examples) | Maven and Gradle |
|
|
238
|
+
| Spring Boot | Projects with Spring Boot markers | 4.0.1 |
|
|
239
|
+
| Java in generated Dockerfiles | ≥17 (generator validation) | 25 default in sample config |
|
|
240
|
+
|
|
241
|
+
The reference sample uses bleeding-edge versions to stress-test generator output and benchmark scenarios. Your project does not need to match those versions to use the CLI.
|
|
242
|
+
|
|
243
|
+
## Project docs
|
|
244
|
+
|
|
245
|
+
Documentation uses three status labels:
|
|
246
|
+
|
|
247
|
+
| Status | Meaning |
|
|
248
|
+
|---|---|
|
|
249
|
+
| **Implemented** | Shipped CLI behavior, runbooks, ADRs, or committed reference artifacts |
|
|
250
|
+
| **Experimental** | Scaffold or opt-in capability — documented with explicit limits; not production-ready |
|
|
251
|
+
| **Roadmap** | Planned capability or doc product not shipped yet |
|
|
252
|
+
|
|
253
|
+
### Implemented
|
|
254
|
+
|
|
255
|
+
- `docs/project-detection.md` — Maven/Gradle detection boundaries and monorepo workflows
|
|
256
|
+
- `docs/POSITIONING.md` — product scope, CI guarantees, sample-tree strategy
|
|
257
|
+
- `docs/digest-pin-runbook.md`
|
|
258
|
+
- `docs/architecture.md`
|
|
259
|
+
- `docs/benchmark-methodology.md`
|
|
260
|
+
- `docs/golden-samples.md`
|
|
261
|
+
- `docs/extensions.md`
|
|
262
|
+
- `docs/security-hardening.md`
|
|
263
|
+
- `docs/observability.md`
|
|
264
|
+
- `docs/kubernetes.md`
|
|
265
|
+
- `docs/adr/README.md`
|
|
266
|
+
- `docs/multiarch.md`
|
|
267
|
+
- `docs/onboarding.md`
|
|
268
|
+
- `docs/team-adoption.md`
|
|
269
|
+
- `docs/troubleshooting.md`
|
|
270
|
+
- `docs/typing-roadmap.md` — gradual mypy strictness and module rollout plan
|
|
271
|
+
- `docs/jvm-optimization.md`
|
|
272
|
+
- `docs/distribution.md`
|
|
273
|
+
- `docs/presentation/README.md` — Reveal.js decks: ownership, update cadence, commit/publish policy
|
|
274
|
+
- `docs/example-gallery.md` — index of committed Dockerfile and benchmark JSON examples under `docs/examples/`
|
|
275
|
+
- `docs/compatibility-matrix.md` — descriptive support ranges (Java 17+, Python 3.10+, etc.)
|
|
276
|
+
- `SECURITY.md`
|
|
277
|
+
- `CONTRIBUTING.md`
|
|
278
|
+
|
|
279
|
+
### Experimental
|
|
280
|
+
|
|
281
|
+
- `docs/native-image-roadmap.md` — `native-aot` recipe and scenario 07 scaffold; runner skips native by default; production native-image workflow remains roadmap
|
|
282
|
+
|
|
283
|
+
### Roadmap
|
|
284
|
+
|
|
285
|
+
- `docs/benchmark-dashboard.md` — standalone trend dashboard (presentation decks and `benchmark analyze` JSON are substitutes today)
|
|
286
|
+
|
|
287
|
+
## Comparison with adjacent tools
|
|
288
|
+
|
|
289
|
+
| Tool | Focus | What springdocker adds |
|
|
290
|
+
|---|---|---|
|
|
291
|
+
| Jib | Dockerless image build | benchmark-aware Dockerfile and runtime tuning workflows |
|
|
292
|
+
| Buildpacks | Opinionated platform build | explicit Dockerfile generation and benchmark artifacts |
|
|
293
|
+
| Manual Dockerfiles | Full control | project detection, config, and repeatable benchmark analysis |
|
|
294
|
+
|
|
295
|
+
## Sample project docs
|
|
296
|
+
|
|
297
|
+
- `docs/golden-samples.md` - fixture walkthroughs, CI coverage, and variant coverage
|
|
298
|
+
- `samples/java-spring-docker/README.md` - full benchmark sample app
|
|
299
|
+
- `samples/java-spring-docker/HELP.md`
|
|
300
|
+
- `samples/java-spring-docker/k8s/kustomization.yaml`
|
|
301
|
+
- `samples/java-spring-docker/tools/README.md`
|
|
302
|
+
|
|
303
|
+
## Contributing
|
|
304
|
+
|
|
305
|
+
Clone the repository and use an editable install — see [CONTRIBUTING.md](CONTRIBUTING.md). The main package is under `src/springdocker/`. Run `pytest` (≥80% line coverage gate), `ruff check src tests`, and `mypy src` before pushing changes.
|