Repository navigation
build(api): the api image is built by Cloud Native Buildpacks, with no shell and no Dockerfile - #2501
Merged
Merged
Conversation
…o shell and no Dockerfile bootBuildImage builds the api with Paketo's tiny Java builder, pinned by tag and digest and bumped by a Renovate regex manager; the run image is the one the builder names. The buildpack trains the AOT cache under the training profile, with throwaway keys drawn per build, and G1 is appended to every start's JAVA_TOOL_OPTIONS. Native memory tracking and Spring Cloud Bindings, Paketo defaults nothing reads, are off. services/api/Dockerfile is gone. Paketo's memory calculator adds an -Xmx that overrides a heap percentage, so the Deployment and the migrate Job name -Xmx and -XX:MaxDirectMemorySize=64M in JAVA_TOOL_OPTIONS, and the calculator refuses a JVM that does not fit its limit. check-aot-cache.sh now reads those limits and options from the manifests and boots the image with each under -XX:AOTMode=on. A build-api-image action builds the image into the runner's daemon, with the buildpacks' build cache restored from the Actions cache by builder digest, and smoke-boots it. The pull request check builds from api-static's jar; the main and release builds push the image, and the merge job attests the api's manifest list with an SBOM from syft and build provenance, pushed beside it, as well as signing it. The runbooks work without a shell: break-glass starts java through the buildpack launcher with its profile on the command line, and on random ports, since the web-application-type=none it used refused to start; the restore rehearsal lists live uploads from a read-only pod mounting the storage claim, and restores them as the cnb user; bringup copies uploads through such a pod. Architecture ADR-015 records the decisions and amends ADR-013. Part of #2449
Contributor
Changes
No production or test lines added. Coverage
Patch coverage: this pull request changes no line that coverage measures. |
…he build says less Part of #2449
9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #2449
Part of #2440
What changes
The api image is built by Cloud Native Buildpacks: Gradle's
bootBuildImagewith Paketo's tiny Java builder. It has no shell and no Dockerfile;services/api/Dockerfileis gone. Architecture ADR-015 records the decisions and amends ADR-013.paketobuildpacks/builder-noble-java-tiny:0.0.197is pinned by digest inservices/api/build.gradle.kts, and a new Renovate regex manager bumps it. The builder names its run image (ubuntu-noble-run-tiny) by version, so that one bump moves the JRE and the run image together. The image runs as the buildpack'scnbuser (1002:1001).BP_JVM_AOTCACHE_ENABLEDturns it on. The training run getsTRAINING_RUN_JAVA_TOOL_OPTIONSwith:trainingprofile andspring.context.exit=onRefresh;MaxRAM=2gand G1;-XX:+UseG1GCis appended to every start'sJAVA_TOOL_OPTIONS. Without it, the migrate Job's 1536 Mi would get Serial and ignore the cache.SPRING_PROFILES_ACTIVEdefaults toprod.-Xmx. I measured that it silently overrides a-XX:MaxRAMPercentage, so the ticket's "heap percentage" would not work.JAVA_TOOL_OPTIONS=-Xmx1200M -XX:MaxDirectMemorySize=64M.-Xmx640M -XX:MaxDirectMemorySize=64M.CI
New
.github/actions/build-api-imageaction:bootBuildImageinto the runner's daemon;The launch cache is not saved: it is about 750 MB of the layers of the build that just ran.
Smoke boot.
scripts/check-aot-cache.shnow reads each pod's limits andJAVA_TOOL_OPTIONSfrom the two manifests, so it can't drift from them, and boots under-XX:AOTMode=on.Pull requests.
Build Image (api)builds fromapi-static's jar, without compiling it again.Main and release builds. The image is smoke-booted before it is pushed. The merge job then signs the api's manifest list with cosign, as before. A buildpack build records no BuildKit provenance or SBOM, so the merge job also:
Runbooks without a shell
javathrough the buildpack launcher (/cnb/lifecycle/launcher -- java -Xmx400M -cp runner.jar …), with its profile on the command line.--spring.main.web-application-type=nonenever worked:SecurityConfigneeds the servlet context. The run now uses--server.port=0 --management.server.port=0instead.ApplicationReady, where the break-glass command runs. The command itself still needs production's database and Vault.api-storageread-only, so the rehearsal still writes nothing. Uploads are restored as thecnbuser.Verified locally
shis not found.AOTMode=on, with G1.After merge
These criteria can only be checked in production, after a release:
gh attestation verify,cosign verify);The release also changes how heap is sized: an explicit 1200M, where the old image's
MaxRAMPercentage=75gave about 1.5G.