├── .DS_Store ├── .devcontainer.json ├── .github └── workflows │ └── hugo.yaml ├── .gitignore ├── .gitpod.yml ├── .vscode ├── settings.json └── tasks.json ├── README.adoc ├── go ├── helloworld │ └── helloworld.go ├── httpserver.go └── webapp │ └── main.go ├── history ├── java-native └── simplecode │ ├── .gitignore │ ├── build.gradle │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle │ └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── simplecode │ │ │ └── SimplecodeApplication.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ └── example │ └── simplecode │ └── SimplecodeApplicationTests.java ├── micronaut ├── .gitignore ├── README.md ├── micronaut-cli.yml ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── Application.java │ └── resources │ │ ├── application.yml │ │ └── logback.xml │ └── test │ └── java │ └── com │ └── example │ └── SimplecodeTest.java ├── pics ├── .DS_Store ├── 001-overview.png ├── 040-Container-Image.png ├── 050-Dockerfile.png ├── 055-Dockerfile-Buildkit-parallel.png ├── 056-Dockerfile-MountCache.png ├── 061-considerations.png ├── 090-jib.png ├── 104-buildpacks-flow.png └── 108-paketo-springboot.png ├── react ├── .npmrc ├── package.json ├── project.toml ├── public │ └── index.html └── src │ ├── App.css │ ├── App.js │ ├── index.css │ └── index.js ├── springboot ├── .classpath ├── .mvn │ └── wrapper │ │ ├── MavenWrapperDownloader.java │ │ └── maven-wrapper.properties ├── .settings │ ├── org.eclipse.core.resources.prefs │ ├── org.eclipse.jdt.apt.core.prefs │ ├── org.eclipse.jdt.core.prefs │ └── org.eclipse.m2e.core.prefs ├── .vscode │ └── settings.json ├── Dockerfile ├── Dockerfile-jlink-alpine ├── Dockerfile-jlink-bookworm ├── Dockerfile-multistage-builder ├── Dockerfile-multistage-cache ├── Dockerfile-multistage-layered ├── Dockerfile-multistage-layered-jvm-flags ├── Dockerfile-multistage-layered-otel-agent ├── Dockerfile-new-user ├── Dockerfile-simple-adoptopenjdk-11 ├── Dockerfile-simple-ibm-semeru ├── Dockerfile-simple-temurin ├── Dockerfile-simple-temurin-JVMflags ├── Dockerfile-simple-ubuntu ├── Dockerfile-ultimate ├── build │ ├── bootJarMainClassName │ ├── bootRunMainClassName │ ├── resources │ │ └── main │ │ │ └── application.properties │ └── tmp │ │ ├── bootJar │ │ └── MANIFEST.MF │ │ └── compileJava │ │ └── source-classes-mapping.txt ├── buildAll.sh ├── buildpacks.yml ├── gradlex │ ├── .classpath │ ├── .settings │ │ └── org.eclipse.buildship.core.prefs │ ├── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── mvnw ├── mvnw.cmd ├── pom.xml ├── runAll.sh └── src │ ├── main │ ├── java │ │ └── de │ │ │ └── maeddes │ │ │ └── simplecode │ │ │ └── SimplecodeApplication.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── de │ └── maeddes │ └── simplecode │ └── SimplecodeApplicationTests.java ├── stuff ├── Dockerfile-bellsoft ├── Dockerfile-multistage-experimental-cache ├── Dockerfile-s2i ├── braindump └── walkthrough.adoc ├── tutorial ├── .gitignore ├── .hugo_build.lock ├── README.md ├── archetypes │ └── default.md ├── config.toml ├── content │ ├── _index.md │ ├── buildpacks │ │ └── _index.md │ ├── dockerfiles │ │ └── _index.md │ ├── jib │ │ └── _index.md │ ├── multistage │ │ └── _index.md │ └── tooling │ │ └── _index.md ├── hugo.toml └── layouts │ ├── partials │ ├── custom-footer.html │ ├── custom-header.html │ └── logo.html │ └── shortcodes │ └── quizdown.html └── tutorial_tmp ├── Dockerfile ├── entrypoint.sh └── static └── css ├── chroma-github.css └── theme-relearn-light.css /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maeddes/java-and-container/fcd3ccd8eacf220c71d24703bfc69b26c6de12e4/.DS_Store -------------------------------------------------------------------------------- /.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Java", 3 | "image": "mcr.microsoft.com/devcontainers/base:bullseye", 4 | "runArgs": [ 5 | "--privileged" 6 | ], 7 | "postCreateCommand": "(curl -sSL https://github.com/buildpacks/pack/releases/download/v0.36.0/pack-v0.36.0-linux.tgz | sudo tar -C /usr/local/bin/ --no-same-owner -xzv pack)", 8 | 9 | "features": { 10 | "ghcr.io/devcontainers/features/java:latest": { 11 | "jdkDistro": "tem", 12 | "installGradle": true, 13 | "installMaven": true 14 | }, 15 | "docker-in-docker": "latest", 16 | "github-cli": "latest" 17 | }, 18 | 19 | "customizations": { 20 | "vscode": { 21 | "extensions": [ 22 | "vscjava.vscode-java-pack", 23 | "redhat.java", 24 | "vscjava.vscode-maven", 25 | "vscjava.vscode-java-dependency", 26 | "VisualStudioExptTeam.vscodeintellicode", 27 | "vscjava.vscode-java-debug", 28 | "vscjava.vscode-spring-initializr", 29 | "ms-azuretools.vscode-docker" 30 | ] 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.github/workflows/hugo.yaml: -------------------------------------------------------------------------------- 1 | # Sample workflow for building and deploying a Hugo site to GitHub Pages 2 | name: Deploy Hugo site to Pages 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: 8 | - main 9 | paths: 10 | - 'tutorial/**' 11 | - '.github/**' 12 | # Allows you to run this workflow manually from the Actions tab 13 | workflow_dispatch: 14 | 15 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 16 | permissions: 17 | contents: read 18 | pages: write 19 | id-token: write 20 | 21 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 22 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 23 | concurrency: 24 | group: "pages" 25 | cancel-in-progress: false 26 | 27 | # Default to bash 28 | defaults: 29 | run: 30 | shell: bash 31 | 32 | jobs: 33 | # Build job 34 | build: 35 | runs-on: ubuntu-latest 36 | env: 37 | HUGO_VERSION: 0.126.0 38 | THEME_VERSION: 6.0.0 39 | steps: 40 | - name: Install Hugo CLI 41 | run: | 42 | wget --quiet -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ 43 | && sudo dpkg -i ${{ runner.temp }}/hugo.deb 44 | - name: Install Dart Sass 45 | run: sudo snap install dart-sass 46 | - name: Checkout 47 | uses: actions/checkout@v4 48 | with: 49 | submodules: recursive 50 | fetch-depth: 0 51 | - name: Install Hugo Theme 52 | run: | 53 | ls -lah \ 54 | && wget --quiet -O "theme.tar.gz" "https://github.com/McShelby/hugo-theme-relearn/archive/refs/tags/${THEME_VERSION}.tar.gz" \ 55 | && mkdir --parents ./tutorial/themes/hugo-theme-relearn-main \ 56 | && tar -xf "theme.tar.gz" --directory ./tutorial/themes/hugo-theme-relearn-main --strip-components=1 57 | - name: Setup Pages 58 | id: pages 59 | uses: actions/configure-pages@v4 60 | - name: Install Node.js dependencies 61 | run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true" 62 | - name: Build with Hugo 63 | env: 64 | # For maximum backward compatibility with Hugo modules 65 | HUGO_ENVIRONMENT: production 66 | HUGO_ENV: production 67 | TZ: America/Los_Angeles 68 | run: | 69 | cd ./tutorial \ 70 | && hugo \ 71 | --gc \ 72 | --minify \ 73 | --baseURL "${{ steps.pages.outputs.base_url }}/" 74 | - name: Upload artifact 75 | uses: actions/upload-pages-artifact@v3 76 | with: 77 | path: ./tutorial/public 78 | 79 | # Deployment job 80 | deploy: 81 | environment: 82 | name: github-pages 83 | url: ${{ steps.deployment.outputs.page_url }} 84 | runs-on: ubuntu-latest 85 | needs: build 86 | steps: 87 | - name: Deploy to GitHub Pages 88 | id: deployment 89 | uses: actions/deploy-pages@v4 90 | - name: Output URL 91 | run: echo ${{ steps.deployment.outputs.page_url }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | **/target/ 4 | 5 | tutorial_tmp 6 | 7 | 8 | **/.gradle 9 | .project 10 | 11 | # Log file 12 | *.log 13 | 14 | # BlueJ files 15 | *.ctxt 16 | 17 | # Mobile Tools for Java (J2ME) 18 | .mtj.tmp/ 19 | 20 | # Package Files # 21 | *.jar 22 | *.war 23 | *.nar 24 | *.ear 25 | *.zip 26 | *.tar.gz 27 | *.rar 28 | 29 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 30 | hs_err_pid* 31 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | image: maeddes/gitpod:full 2 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "java.configuration.updateBuildConfiguration": "automatic", 3 | "java.completion.enabled": false, 4 | "java.debug.settings.enableRunDebugCodeLens": false, 5 | "java.compile.nullAnalysis.mode": "automatic" 6 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "Build Container", 6 | "type": "shell", 7 | "command": "docker build -t java-app:test -f springboot/Dockerfile-ultimate", 8 | "problemMatcher": [] 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = Lab/Walkthrough instructions - Container Builds 2 | :sectnums: 3 | :toc: 4 | 5 | image::pics/001-overview.png[Container Build Options,640] 6 | 7 | == About 8 | 9 | This lab will walk you through steps to build container images with various technologies. 10 | 11 | * Slides: https://speakerdeck.com/maeddes/options-galore-from-source-code-to-container-image 12 | * Recording (English): https://www.youtube.com/watch?v=HFhIqfKn_XIdock 13 | * Recording (German): https://www.youtube.com/watch?v=ga8iqQ25lUY 14 | * Carlos Repo: https://github.com/carlosbarragan/java-containers-demo 15 | 16 | == Prereqs 17 | 18 | Mandatory: 19 | 20 | * A Docker environment and Docker CLI https://docs.docker.com/get-docker/ 21 | * Pack CLI for Cloud-Native Buildpacks https://buildpacks.io/docs/tools/pack/ 22 | * Clone/Download this repo: https://github.com/maeddes/options-galore-container-build 23 | 24 | Recommended: 25 | 26 | * A Java (21 or later) Development Kit for Java examples, e.g https://adoptopenjdk.net/ 27 | 28 | Optional: 29 | 30 | * Dive tool https://github.com/wagoodman/dive 31 | 32 | Links: 33 | 34 | * https://home.robusta.dev/blog/stop-using-cpu-limits 35 | 36 | === Validation 37 | 38 | Validate docker installation. 39 | 40 | [source] 41 | ---- 42 | docker version 43 | ---- 44 | 45 | Should display output like (version might differ): 46 | 47 | ---- 48 | Client: Docker Engine - Community 49 | Version: 25.0.3 50 | API version: 1.44 51 | ... 52 | 53 | Server: Docker Engine - Community 54 | Engine: 55 | Version: 25.0.3 56 | API version: 1.44 (minimum version 1.24) 57 | ---- 58 | 59 | Validate Java. 60 | 61 | [source] 62 | ---- 63 | java --version 64 | ---- 65 | 66 | Should display output like (version might differ): 67 | 68 | ---- 69 | openjdk 21.0.7 2023-04-18 70 | OpenJDK Runtime Environment (build 21.0.7+7-Ubuntu-0ubuntu120.04) 71 | OpenJDK 64-Bit Server VM (build 21.0.7+7-Ubuntu-0ubuntu120.04, mixed mode, sharing) 72 | ---- 73 | 74 | == Dockerfile Exercises 75 | 76 | === Set environment and build code 77 | 78 | Download/clone the repo and change to the root folder. If you are running in gitpod,codespaces or using devcontainer, you can skip this step. 79 | [source, bash] 80 | ---- 81 | git clone https://github.com/maeddes/options-galore-container-build 82 | ---- 83 | 84 | 85 | Note: Without git CLI you can download the repo as zip file here: https://github.com/maeddes/options-galore-container-build/archive/refs/heads/main.zip 86 | Extract it and change your command line shell to the root folder. 87 | 88 | [source, bash] 89 | ---- 90 | cd options-galore-container-build 91 | ---- 92 | 93 | Build the code: 94 | 95 | Change to the Java sample app 96 | [source, bash] 97 | ---- 98 | cd java 99 | ---- 100 | 101 | Option 1 (with local JDK installed) 102 | [source] 103 | ---- 104 | ./mvnw clean package 105 | ---- 106 | 107 | 108 | 109 | Validate build artefact (timestamps will of course be different) 110 | [source] 111 | ---- 112 | ls -ltr ./target/simplecode-0.0.1-SNAPSHOT.jar 113 | ---- 114 | ---- 115 | -rw-r--r-- 1 root root 20951064 May 5 11:47 ./target/simplecode-0.0.1-SNAPSHOT.jar 116 | ---- 117 | 118 | === Classic Dockerfile 119 | 120 | image::pics/050-Dockerfile.png[Classic Dockerfile] 121 | 122 | Observe contents of Dockerfile-simple-ubuntu 123 | 124 | [source] 125 | ---- 126 | cat Dockerfile-simple-ubuntu 127 | ---- 128 | 129 | ---- 130 | FROM ubuntu:22.04 131 | RUN apt update && apt install openjdk-21-jre-headless -y 132 | COPY target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 133 | CMD ["java","-jar","/opt/app.jar"] 134 | ---- 135 | 136 | Build first image with this Dockerfile: 137 | 138 | [source] 139 | ---- 140 | docker build -f Dockerfile-simple-ubuntu -t java-app:v-simple-ubuntu . 141 | ---- 142 | 143 | Build images with other predefined base images: 144 | 145 | [source] 146 | ---- 147 | docker build -f Dockerfile-simple-temurin -t java-app:v-simple-temurin . 148 | ---- 149 | 150 | [source] 151 | ---- 152 | docker build -f Dockerfile-simple-ibm-semeru -t java-app:v-simple-ibm-semeru . 153 | ---- 154 | 155 | Validate images in local repo 156 | 157 | [source] 158 | ---- 159 | docker images 160 | ---- 161 | 162 | ---- 163 | REPOSITORY TAG IMAGE ID CREATED SIZE 164 | java-app v-simple-ibm-semeru 3a7c058097d9 8 seconds ago 300MB 165 | java-app v-simple-temurin 62c5ca75dad1 32 seconds ago 292MB 166 | java-app v-simple-ubuntu a491383f3f53 2 minutes ago 400MB---- 167 | ---- 168 | 169 | Observe build history and differences of the 3 images 170 | 171 | [source] 172 | ---- 173 | docker history java-app:v-simple-ubuntu 174 | docker history java-app:v-simple-temurin 175 | docker history java-app:v-simple-ibm-semeru 176 | ---- 177 | 178 | You will observe different base layers and structure, but always the same top layer: 179 | ---- 180 | IMAGE CREATED CREATED BY SIZE COMMENT 181 | 7209f28736c8 3 minutes ago /bin/sh -c #(nop) CMD ["java" "-jar" "/opt/… 0B 182 | e5385e2e3146 3 minutes ago /bin/sh -c #(nop) COPY file:90a1db2252f31169… 19MB 183 | ---- 184 | 185 | Optional: Use tool "dive" to show detailed history of image: 186 | 187 | [source] 188 | ---- 189 | dive java-app:v-simple-ubuntu 190 | ---- 191 | [source] 192 | ---- 193 | dive java-app:v-simple-temurin 194 | ---- 195 | [source] 196 | ---- 197 | dive java-app:v-simple-ibm-semeru 198 | ---- 199 | 200 | Usage: ctrl+l (ensure layer changes) ctrl+u (uncheck unmodified) for layer switch 201 | 202 | === Multi-Stage 203 | 204 | image::pics/055-Dockerfile-Buildkit-parallel.png[Multi-Stage Dockerfiles] 205 | 206 | Build image with Multistage Dockerfile: 207 | 208 | [source] 209 | ---- 210 | docker build -f Dockerfile-multistage-builder -t java-app:v-multistage-builder . 211 | ---- 212 | 213 | This will take a while as all the maven dependencies need to be downloaded. 214 | 215 | Validate history: 216 | 217 | [source] 218 | ---- 219 | docker history java-app:v-multistage-builder 220 | ---- 221 | 222 | Explore docker images: 223 | 224 | [source] 225 | ---- 226 | docker images 227 | ---- 228 | 229 | ---- 230 | REPOSITORY TAG IMAGE ID CREATED SIZE 231 | java-app v-multistage-builder 816512fee0cd 21 seconds ago 291MB 232 | ---- 233 | 234 | Perform a slight modification in the source code which does not affect the behaviour of the application. 235 | You can use the editor 'nano' to execute this: 236 | 237 | [source] 238 | ---- 239 | nano src/main/java/de/maeddes/simplecode/SimplecodeApplication.java 240 | ---- 241 | 242 | Locate the method hello() 243 | 244 | [java] 245 | ---- 246 | @GetMapping("/") 247 | String hello(){ 248 | 249 | logger.info("Call to hello method on instance: " + getInstanceId()); 250 | return getInstanceId()+" Hello, Container people ! "; 251 | 252 | } 253 | ---- 254 | 255 | and just add some characters to the method name, e.g. 256 | 257 | [java] 258 | ---- 259 | String helloABC(){ 260 | ---- 261 | 262 | And save it using Ctrl+X and confirm with 'Y'. 263 | 264 | Now you can repeat the docker build call. 265 | 266 | [source] 267 | ---- 268 | docker build -f Dockerfile-multistage-builder -t java-app:v-multistage-builder . 269 | ---- 270 | 271 | You can observe that all the dependencies will need to get downloaded again. This method does not cache anything. 272 | 273 | === BuildKit 274 | 275 | 276 | Build with multistage cache option: 277 | 278 | image::pics/056-Dockerfile-MountCache.png[Dockerfile with Cache] 279 | 280 | [source] 281 | ---- 282 | docker build -f Dockerfile-multistage-cache -t java-app:v-multistage-cache . 283 | ---- 284 | 285 | Change the code and rebuild: 286 | 287 | You can use an editor to change a method name in 288 | ---- 289 | src/main/java/de/maeddes/simplecode/SimplecodeApplication.java 290 | ---- 291 | or simply execute 292 | 293 | [source] 294 | ---- 295 | sed -i 's/hello/helloABC/g' src/main/java/de/maeddes/simplecode/SimplecodeApplication.java 296 | ---- 297 | (Linux) 298 | 299 | or 300 | 301 | [source] 302 | ---- 303 | sed -i '' 's/hello/helloABC/g' src/main/java/de/maeddes/simplecode/SimplecodeApplication.java 304 | ---- 305 | (Mac) 306 | 307 | Rebuild and observe faster build through caching: 308 | 309 | [source] 310 | ---- 311 | docker build -f Dockerfile-multistage-cache -t java-app:v-multistage-cache . 312 | ---- 313 | 314 | Observe the history to validate that top layer is still 'monolithic': 315 | 316 | [source] 317 | ---- 318 | docker history java-app:v-multistage-cache 319 | ---- 320 | 321 | Build the code with a layered jar approach: 322 | 323 | image::pics/061-considerations.png[Layer considerations for Java] 324 | 325 | [source] 326 | ---- 327 | docker build -f Dockerfile-multistage-layered -t java-app:layered . 328 | ---- 329 | 330 | Display layered state 331 | 332 | [source] 333 | ---- 334 | docker history java-app:layered 335 | ---- 336 | 337 | ---- 338 | IMAGE CREATED CREATED BY SIZE COMMENT 339 | de2cb7c4be82 8 seconds ago ENTRYPOINT ["java" "org.springframework.boot… 0B buildkit.dockerfile.v0 340 | 8 seconds ago COPY application/application/ ./ # buildkit 6.12kB buildkit.dockerfile.v0 341 | 8 seconds ago COPY application/snapshot-dependencies/ ./ #… 0B buildkit.dockerfile.v0 342 | 8 seconds ago COPY application/spring-boot-loader/ ./ # bu… 245kB buildkit.dockerfile.v0 343 | 8 seconds ago COPY application/dependencies/ ./ # buildkit 18.9MB buildkit.dockerfile.v0 344 | ---- 345 | 346 | Finally have a look at the Dockerfile with specific JVM flags: 347 | 348 | [source] 349 | ---- 350 | cat Dockerfile-multistage-layered-jvm-flags 351 | ---- 352 | 353 | in the final line you can see how to apply alternative settings here. 354 | 355 | ---- 356 | ENTRYPOINT ["java","-XX:+UseParallelGC","-XX:MaxRAMPercentage=75","org.springframework.boot.loader.JarLauncher"] 357 | ---- 358 | 359 | 360 | == Jib 361 | 362 | The following steps show how to build container images with the jib-maven plugin. 363 | 364 | image::pics/090-jib.png[Jib from Google] 365 | 366 | Again the use of the local maven wrapper (mvnw) will require a local JDK installation. 367 | If it's not present use option 2. 368 | 369 | Option 1: 370 | [source] 371 | ---- 372 | ./mvnw compile com.google.cloud.tools:jib-maven-plugin:3.4.4:dockerBuild -Dimage=java-app:jib -Djib.from.image=eclipse-temurin:21-jre 373 | ---- 374 | 375 | In this case the *:dockerBuild* part will instruct the plugin to build to the local docker daemon. 376 | The *-Dimage* parameter will specify the image name tag. 377 | 378 | If you have a docker account you can login and push directly to the docker hub using: 379 | (Replace with your own username) 380 | 381 | [source] 382 | ---- 383 | ./mvnw compile com.google.cloud.tools:jib-maven-plugin:3.4.4:build -Dimage=/java-app:jib -Djib.from.image=eclipse-temurin:21-jre 384 | ---- 385 | 386 | Another option is to export the image directly to a tar. Use the following command. 387 | 388 | [source] 389 | ---- 390 | ./mvnw compile com.google.cloud.tools:jib-maven-plugin:3.4.4:buildTar -Dimage=java-app:jib -Djib.from.image=eclipse-temurin:21-jre 391 | ---- 392 | 393 | You will see an output saying 394 | 395 | After that you can import the image into the local registry. 396 | 397 | [source] 398 | ---- 399 | docker load -i target/jib-image.tar 400 | ---- 401 | 402 | ---- 403 | not showing any more 404 | 15bbc04e2cf6: Loading layer [==================================================>] 41.71MB/41.71MB 405 | 7f270d883779: Loading layer [==================================================>] 16.82MB/16.82MB 406 | 496ff124a7de: Loading layer [==================================================>] 213B/213B 407 | 965a8d44c836: Loading layer [==================================================>] 1.345kB/1.345kB 408 | 5e91304a655b: Loading layer [==================================================>] 219B/219B 409 | Loaded image: java-app:jib 410 | ---- 411 | 412 | Option 2: 413 | 414 | Without local maven you can only perform the tar build and direct import via load. 415 | 416 | [source] 417 | ---- 418 | docker run -it --rm --name my-maven-project -v "$(pwd)":/opt/app -w /opt/app maven:3.6.3-jdk-11 mvn compile com.google.cloud.tools:jib-maven-plugin:3.3.1:buildTar -Dimage=java-app:jib 419 | ---- 420 | 421 | Load the exported tar file as image into the local registry. 422 | 423 | [source] 424 | ---- 425 | docker load -i target/jib-image.tar 426 | ---- 427 | 428 | ---- 429 | 15bbc04e2cf6: Loading layer [==================================================>] 41.71MB/41.71MB 430 | 7f270d883779: Loading layer [==================================================>] 16.82MB/16.82MB 431 | 496ff124a7de: Loading layer [==================================================>] 213B/213B 432 | 965a8d44c836: Loading layer [==================================================>] 1.345kB/1.345kB 433 | 5e91304a655b: Loading layer [==================================================>] 219B/219B 434 | Loaded image: java-app:jib 435 | ---- 436 | 437 | Both options - final steps: 438 | 439 | Now that you've built and loaded the image into the local registry using one of the options above, inspect the layered structure of the image. 440 | 441 | [source] 442 | ---- 443 | docker history java-app:jib 444 | ---- 445 | 446 | ---- 447 | IMAGE CREATED CREATED BY SIZE COMMENT 448 | 2275828677a8 N/A jib-maven-plugin:3.4.4 1.66kB jvm arg files 449 | N/A jib-maven-plugin:3.4.4 2.46kB classes 450 | N/A jib-maven-plugin:3.4.4 1B resources 451 | N/A jib-maven-plugin:3.4.4 23.1MB dependencies 452 | ---- 453 | 454 | Optional: Perform some small modifications in the code similar to the ones during the Dockerfile exercise. 455 | Re-run the build steps and observe the caching and improved performance. 456 | 457 | Note: All of the previous examples referenced the jib plugin directly in the maven call. An alternative (and probably the clean way) to the steps above is to add the plugin to your pom.xml: 458 | 459 | The tag in the following xml sets the target image path in the image registry. In our case we are using the local registry and thus just providing the image tag. 460 | 461 | You can add the following plugin to your pom.xml 462 | [source] 463 | ---- 464 | 465 | com.google.cloud.tools 466 | jib-maven-plugin 467 | 3.4.4 468 | 469 | 470 | eclipse-temurin:21-jre 471 | 472 | 473 | java-app:jib-v2.0 474 | 475 | 476 | 477 | ---- 478 | 479 | In this case the invocation looks much simpler. 480 | 481 | [source] 482 | ---- 483 | ./mvnw compile jib:dockerBuild 484 | ---- 485 | 486 | The *:build* and *:buildTar* options work accordingly. 487 | 488 | It is of course also possible to define custom JVM arguments with Jib. However this is not possible with a plain mvn call. 489 | You also can of course apply these settings not during build time, but when starting the container: 490 | 491 | [source] 492 | ---- 493 | docker run --env JAVA_TOOL_OPTIONS='-XX:+UseParallelGC -XX:MaxRAMPercentage=75' java-app:jib 494 | ---- 495 | 496 | 497 | == Cloud-native buildpacks 498 | 499 | image::pics/104-buildpacks-flow.png[Cloud-Native Buildpacks] 500 | 501 | Access the pack CLI and list the suggest builders. A builder includes the buildpacks and environment that will be used for building and running your app. 502 | 503 | 504 | [source] 505 | ---- 506 | pack builder suggest 507 | ---- 508 | 509 | Set a default builder to avoid specifying a builder every time you build. For the examples in this tutorial use the base builder image from Paketo buildpacks. 510 | 511 | [source] 512 | ---- 513 | pack config default-builder paketobuildpacks/builder-jammy-base 514 | ---- 515 | 516 | 517 | 518 | Now all is set to build the container image using the buildpack. Simply execute: 519 | 520 | [source] 521 | ---- 522 | pack build java-app:pack 523 | ---- 524 | 525 | 526 | 527 | The first invocation will take a long time. The builder image is big as it contains all the logic plus buildpacks. 528 | 529 | After it is downloaded can now observe the output - the so-called bill of materials. 530 | This gives detailed information about the build. 531 | 532 | Should display output like: 533 | ---- 534 | ===> ANALYZING 535 | ... 536 | ===> DETECTING 537 | ... 538 | ===> RESTORING 539 | ===> BUILDING 540 | ... 541 | ===> EXPORTING 542 | ... 543 | 544 | Successfully built image java-app:pack^ 545 | ---- 546 | 547 | 548 | Optimize the build with: 549 | 550 | ---- 551 | pack build java-app:pack-compressed --env BP_JVM_JLINK_ENABLED=true 552 | ---- 553 | 554 | If you want to configure specific JVM settings with Paketo Buildpacks you can extend the call to use alternative configuration: 555 | 556 | [source] 557 | ---- 558 | pack build -e BPE_APPEND_JAVA_TOOL_OPTIONS='-XX:+UseParallelGC -XX:MaxRAMPercentage=75' -e BPE_DELIM_JAVA_TOOL_OPTIONS=' ' java-app:pack 559 | ---- 560 | 561 | 562 | Paketo buildpacks can be configured using different for external configuration (Environment Variables, buildpack.yml, Bindings, Procfiles). 563 | 564 | Use an environment variable to configure the JVM version installed by the Java Buildpack and build a new version of the container image 565 | 566 | [source] 567 | ---- 568 | pack build java-app:pack-v2.0 --env BP_JVM_VERSION=11 569 | ---- 570 | 571 | Observe the usage of (JDK 11.0.19, JRE 11.0.19) in the BUILDING phase of the output. 572 | 573 | 574 | Get an overview of the built Images 575 | 576 | [source] 577 | ---- 578 | docker images 579 | ---- 580 | 581 | Using pack it is possible to swap out the underlying OS layers (run image) of an app image with another run image version, without re-building the application. 582 | 583 | Rebase app image with a version pinned run image 584 | 585 | [source] 586 | ---- 587 | pack rebase java-app:pack --run-image paketobuildpacks/run:1.3.48-full-cnb 588 | ---- 589 | 590 | Should display output like: 591 | 592 | ---- 593 | 1.3.48-full-cnb: Pulling from paketobuildpacks/run 594 | 83525de54a98: Already exists 595 | c1dbbbd2a415: Pull complete 596 | 283105c565ee: Pull complete 597 | 7ead7caf102c: Pull complete 598 | Digest: sha256:005e54c4254bd49fa5b0b55fd7b7f16a2654bc6643963dece1cd03f7a0abce24 599 | Status: Downloaded newer image for paketobuildpacks/run:1.3.48-full-cnb 600 | Rebasing java-app:pack on run image paketobuildpacks/run:1.3.48-full-cnb 601 | Saving java-app:pack... 602 | *** Images (a938edc476a8): 603 | java-app:pack 604 | Rebased Image: a938edc476a85ab53d6aa52a5cc6288c1dffdafd9b3654236cf8b62bbce70a83 605 | Successfully rebased image java-app:pack 606 | ---- 607 | 608 | 609 | 610 | == Paketo with Spring Boot and Maven 611 | 612 | image::pics/108-paketo-springboot.png[Paketo, Spring Boot, Maven] 613 | 614 | For a Spring Boot application you can also invoke Paketo Buildpacks directly via maven. 615 | 616 | [source] 617 | ---- 618 | ./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=java-app:paketo 619 | ---- 620 | 621 | 622 | After compiling and testing the code within a standard Maven build, the build-image phase appears in the build log, in which you should observe display output like: 623 | 624 | ---- 625 | ===> DETECTING 626 | ... 627 | ===> ANALYZING 628 | ... 629 | ===> RESTORING 630 | ===> BUILDING 631 | ... 632 | ===> EXPORTING 633 | ... 634 | Successfully built image 'docker.io/library/java-app:paketo' 635 | ---- 636 | 637 | 638 | Get an overview of the built Images 639 | 640 | 641 | == Options 642 | 643 | You have now completed the core exercise. 644 | Feel free to do some modifications yourself. 645 | Suggestions: 646 | * Edit the pom.xml and alternate the Java version (8,11,21 have been tested). 647 | * Do minor or major code modifications and observe changes 648 | * Use dive to analyze the created images. 649 | 650 | 651 | (C) Matthias Haeussler. Free for private purposes. (Re)distribution for commercial purposes not allowed without owner permissions. 652 | -------------------------------------------------------------------------------- /go/helloworld/helloworld.go: -------------------------------------------------------------------------------- 1 | package main 2 | import "fmt" 3 | 4 | func variables() { 5 | 6 | var a = "matthias" 7 | fmt.Println(a) 8 | 9 | var b, c int = 3, 4 10 | fmt.Println(b, c) 11 | 12 | var d = true 13 | fmt.Println(d) 14 | 15 | var e int 16 | fmt.Println(e) 17 | 18 | f := "String" 19 | fmt.Println(f) 20 | } 21 | 22 | 23 | func helloworld() { 24 | fmt.Println("hello world") 25 | fmt.Println(true) 26 | fmt.Println(2+2) 27 | fmt.Println("3 * 3 = ",3*3) 28 | } 29 | 30 | func multiply(a,b int) int{ 31 | 32 | return a*b 33 | } 34 | 35 | func loops(){ 36 | 37 | i := 0; 38 | for i < 10 { 39 | 40 | fmt.Println(i, i, " * ",i, " = ", multiply(i,i)) 41 | i++; 42 | 43 | } 44 | 45 | for j:=0; j <= 10; j++ { 46 | 47 | fmt.Println(j, j, " + ",j, " = ", j+j) 48 | } 49 | } 50 | 51 | 52 | func main(){ 53 | 54 | fmt.Println(" === Basics:") 55 | helloworld() 56 | fmt.Println(" === Variables") 57 | variables() 58 | fmt.Println(" === Loops") 59 | loops() 60 | 61 | } 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /go/httpserver.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "os" 7 | ) 8 | 9 | func hello(w http.ResponseWriter, req *http.Request) { 10 | 11 | fmt.Fprintf(w, "hello\n") 12 | } 13 | 14 | func headers(w http.ResponseWriter, req *http.Request) { 15 | 16 | for name, headers := range req.Header { 17 | for _, h := range headers { 18 | fmt.Fprintf(w, "%v: %v\n", name, h) 19 | } 20 | } 21 | } 22 | 23 | func main() { 24 | 25 | var port = os.Getenv("PORT") 26 | fmt.Println("Listening on port: ",port) 27 | http.HandleFunc("/hello", hello) 28 | http.HandleFunc("/headers", headers) 29 | 30 | http.ListenAndServe(":8090", nil) 31 | } -------------------------------------------------------------------------------- /go/webapp/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "os" 7 | ) 8 | 9 | func hello(w http.ResponseWriter, req *http.Request) { 10 | 11 | fmt.Fprintf(w, "hello\n") 12 | } 13 | 14 | func headers(w http.ResponseWriter, req *http.Request) { 15 | 16 | for name, headers := range req.Header { 17 | for _, h := range headers { 18 | fmt.Fprintf(w, "%v: %v\n", name, h) 19 | } 20 | } 21 | } 22 | 23 | func main() { 24 | 25 | var port = os.Getenv("PORT") 26 | fmt.Println("Listening on port: ",port) 27 | http.HandleFunc("/hello", hello) 28 | http.HandleFunc("/headers", headers) 29 | 30 | http.ListenAndServe(":8090", nil) 31 | } -------------------------------------------------------------------------------- /history: -------------------------------------------------------------------------------- 1 | 1 cd java 2 | 2 docker build -f Dockerfile-simple-temurin -t java-temurin-plain:v1 . 3 | 3 sdk install java 4 | 4 cd target 5 | 5 cd .. 6 | 6 mvn clean install 7 | 7 ps -ef 8 | 8 ./mvnw compile com.google.cloud.tools:jib-maven-plugin:3.3.1:dockerBuild -Dimage=java-app:jib 9 | 9 cd java 10 | 10 mvn compile com.google.cloud.tools:jib-maven-plugin:3.3.1:dockerBuild -Dimage=java-app:jib 11 | 11 docker images 12 | 12 docker ps 13 | 13 docker run -d 7c5 14 | 14 ps -ef 15 | 15 brew install buildpacks/tap/pack 16 | 16 pack 17 | 17 pack config default-builder paketobuildpacks/builder:base 18 | 18 pack build java-app:pack 19 | 19 sudo chmod 666 /var/run/docker.sock 20 | 20 pack build java-app:pack 21 | 21 docker images 22 | 22 docker run -d 16b 23 | 23 docker logs 24 | 24 docker logs ~1~6b 25 | 25 docker logs 16b 26 | 26 docker logs 0db 27 | 27 ps -ef 28 | 28 history > /workspace/history 29 | 29 history > /workspace/options-galore-container-build/history 30 | 1 echo 'TODO: start app' 31 | 2 cd java 32 | 3 docker build -f Dockerfile-simple-temurin -t java-temurin-plain:v1 . 33 | 4 sdk install java 34 | 5 cd target 35 | 6 cd .. 36 | 7 mvn clean install 37 | 8 java -jar target/simplecode-0.0.1-SNAPSHOT.jar 38 | 9 java –XX:+UseParallelGC –XX:MaxRAMPercentage=75 -jar target/simplecode-0.0.1-SNAPSHOT.jar 39 | 10 java 40 | 11 java -XX:-UseParallelGC -jar target/simplecode-0.0.1-SNAPSHOT.jar 41 | 12 java -XX:+UseParallelGC -jar target/simplecode-0.0.1-SNAPSHOT.jar 42 | 13 java -XX:+UseParallelGC –XX:MaxRAMPercentage=75 -jar target/simplecode-0.0.1-SNAPSHOT.jar 43 | 14 java -XX:+UseParallelGC -XX:MaxRAMPercentage=75 -jar target/simplecode-0.0.1-SNAPSHOT.jar 44 | 15 docker build -f Dockerfile-simple-temurin -t java-app-gc:v1 . 45 | 16 docker images 46 | 17 docker run -d d63 47 | 18 docker ps 48 | 19 docker logs 952 49 | 20 docker ps 50 | 21 docker build -f Dockerfile-multistage-layered -t java-final-gc:v1 . 51 | 22 mvn clean 52 | 23 docker build -f Dockerfile-multistage-layered -t java-final-gc:v1 . 53 | 24 docker build 54 | 25 docker build --help 55 | 26 docker build --no-cache -f Dockerfile-multistage-layered -t java-final-gc:v1 . 56 | 27 docker images 57 | 28 docker run -d 747 58 | 29 docker logs 5f3 59 | 30 history 60 | 31 history >> /workspace/options-galore-container-build/history 61 | 46 java -Djarmode=tools -jar application.jar extract --layers --launcher 62 | 47 ls -ltr 63 | 48 ls -ltr application 64 | 49 cd application/ 65 | 50 java org.springframework.boot.loader.JarLauncher 66 | 51 ls 67 | 52 cd application/ 68 | 53 ls 69 | 54 org.springframework.boot.loader.JarLauncher 70 | 55 java org.springframework.boot.loader.JarLauncher 71 | 56 ls -ltr 72 | 57 cd .. 73 | 58 tree 74 | 59 java org.springframework.boot.loader.lanch.JarLauncher 75 | 60 ls 76 | 61 cd application/ 77 | 62 ls 78 | 63 cd .. 79 | 64 cd spring-boot-loader/ 80 | 65 java org.springframework.boot.loader.lanch.JarLauncher 81 | 66 ls 82 | 67 java org.springframework.boot.loader.launch.JarLauncher 83 | 68 ls 84 | 69 cd .. 85 | 70 ls 86 | 71 cd .. 87 | 72 ls 88 | 73 cp -R application/dependencies/ ./ 89 | 74 cp -R application/spring-boot-loader/ ./ 90 | 75 cp -R application/snapshot-dependencies/ ./ 91 | 76 cp -R application/application/ ./ 92 | 77 java org.springframework.boot.loader.launch.JarLauncher 93 | 78 ls 94 | 79 cp -R application/spring-boot-loader/* ./ 95 | 80 ls 96 | 81 cp -R application/application/* ./ 97 | 82 cp -R application/snapshot-dependencies/* ./ 98 | 83 cp -R application/dependencies/* ./ 99 | 84 history 100 | 85 java org.springframework.boot.loader.launch.JarLauncher 101 | 86 wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.8.0/opentelemetry-javaagent.jar 102 | 87 java -javaagent:./opentelemetry-javaagent.jar org.springframework.boot.loader.launch.JarLauncher 103 | 88 history 104 | 89 history > ../../tutorial_tmp/history_layers 105 | -------------------------------------------------------------------------------- /java-native/simplecode/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /java-native/simplecode/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.7.3' 3 | id 'io.spring.dependency-management' version '1.0.13.RELEASE' 4 | id 'java' 5 | 6 | } 7 | 8 | group = 'com.example' 9 | version = '0.0.1-SNAPSHOT' 10 | sourceCompatibility = '11' 11 | 12 | repositories { 13 | maven { url 'https://repo.spring.io/release' } 14 | mavenCentral() 15 | } 16 | 17 | dependencies { 18 | implementation 'org.springframework.boot:spring-boot-starter' 19 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 20 | } 21 | 22 | tasks.named('test') { 23 | useJUnitPlatform() 24 | } 25 | 26 | tasks.named('bootBuildImage') { 27 | builder = 'paketobuildpacks/builder:tiny' 28 | environment = ['BP_NATIVE_IMAGE': 'true'] 29 | } -------------------------------------------------------------------------------- /java-native/simplecode/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maeddes/java-and-container/fcd3ccd8eacf220c71d24703bfc69b26c6de12e4/java-native/simplecode/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /java-native/simplecode/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Mar 24 16:18:23 UTC 2025 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /java-native/simplecode/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /java-native/simplecode/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /java-native/simplecode/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url 'https://repo.spring.io/release' } 4 | mavenCentral() 5 | gradlePluginPortal() 6 | } 7 | } 8 | rootProject.name = 'simplecode' 9 | -------------------------------------------------------------------------------- /java-native/simplecode/src/main/java/com/example/simplecode/SimplecodeApplication.java: -------------------------------------------------------------------------------- 1 | package com.example.simplecode; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SimplecodeApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SimplecodeApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /java-native/simplecode/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /java-native/simplecode/src/test/java/com/example/simplecode/SimplecodeApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.simplecode; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SimplecodeApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /micronaut/.gitignore: -------------------------------------------------------------------------------- 1 | Thumbs.db 2 | .DS_Store 3 | .gradle 4 | build/ 5 | target/ 6 | out/ 7 | .idea 8 | *.iml 9 | *.ipr 10 | *.iws 11 | .project 12 | .settings 13 | .classpath 14 | .factorypath 15 | -------------------------------------------------------------------------------- /micronaut/README.md: -------------------------------------------------------------------------------- 1 | ## Micronaut 2.5.9 Documentation 2 | 3 | - [User Guide](https://docs.micronaut.io/2.5.9/guide/index.html) 4 | - [API Reference](https://docs.micronaut.io/2.5.9/api/index.html) 5 | - [Configuration Reference](https://docs.micronaut.io/2.5.9/guide/configurationreference.html) 6 | - [Micronaut Guides](https://guides.micronaut.io/index.html) 7 | --- 8 | 9 | ## Feature http-client documentation 10 | 11 | - [Micronaut HTTP Client documentation](https://docs.micronaut.io/latest/guide/index.html#httpClient) 12 | 13 | -------------------------------------------------------------------------------- /micronaut/micronaut-cli.yml: -------------------------------------------------------------------------------- 1 | applicationType: default 2 | defaultPackage: com.example 3 | testFramework: junit 4 | sourceLanguage: java 5 | buildTool: gradle 6 | features: [annotation-api, app-name, gradle, http-client, java, java-application, junit, logback, netty-server, readme, shade, yaml] 7 | -------------------------------------------------------------------------------- /micronaut/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | com.example 6 | simplecode 7 | 0.1 8 | ${packaging} 9 | 10 | 11 | io.micronaut 12 | micronaut-parent 13 | 2.5.9 14 | 15 | 16 | 17 | jar 18 | 11 19 | 11 20 | 2.5.9 21 | com.example.Application 22 | netty 23 | 24 | 25 | 26 | 27 | central 28 | https://repo.maven.apache.org/maven2 29 | 30 | 31 | 32 | 33 | 34 | io.micronaut 35 | micronaut-inject 36 | compile 37 | 38 | 39 | io.micronaut 40 | micronaut-validation 41 | compile 42 | 43 | 44 | org.junit.jupiter 45 | junit-jupiter-api 46 | test 47 | 48 | 49 | org.junit.jupiter 50 | junit-jupiter-engine 51 | test 52 | 53 | 54 | io.micronaut.test 55 | micronaut-test-junit5 56 | test 57 | 58 | 59 | io.micronaut 60 | micronaut-http-client 61 | compile 62 | 63 | 64 | io.micronaut 65 | micronaut-http-server-netty 66 | compile 67 | 68 | 69 | io.micronaut 70 | micronaut-runtime 71 | compile 72 | 73 | 74 | javax.annotation 75 | javax.annotation-api 76 | compile 77 | 78 | 79 | ch.qos.logback 80 | logback-classic 81 | runtime 82 | 83 | 84 | 85 | 86 | 87 | 88 | io.micronaut.build 89 | micronaut-maven-plugin 90 | 91 | 92 | 93 | org.apache.maven.plugins 94 | maven-compiler-plugin 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | -Amicronaut.processing.group=com.example 103 | -Amicronaut.processing.module=simplecode 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /micronaut/src/main/java/com/example/Application.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import io.micronaut.runtime.Micronaut; 4 | 5 | public class Application { 6 | 7 | public static void main(String[] args) { 8 | Micronaut.run(Application.class, args); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /micronaut/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | micronaut: 2 | application: 3 | name: simplecode 4 | server: 5 | port: 8081 -------------------------------------------------------------------------------- /micronaut/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | 7 | 8 | %cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /micronaut/src/test/java/com/example/SimplecodeTest.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import io.micronaut.runtime.EmbeddedApplication; 4 | import io.micronaut.test.extensions.junit5.annotation.MicronautTest; 5 | import org.junit.jupiter.api.Test; 6 | import org.junit.jupiter.api.Assertions; 7 | 8 | import javax.inject.Inject; 9 | 10 | @MicronautTest 11 | class SimplecodeTest { 12 | 13 | @Inject 14 | EmbeddedApplication application; 15 | 16 | @Test 17 | void testItWorks() { 18 | Assertions.assertTrue(application.isRunning()); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /pics/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maeddes/java-and-container/fcd3ccd8eacf220c71d24703bfc69b26c6de12e4/pics/.DS_Store -------------------------------------------------------------------------------- /pics/001-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maeddes/java-and-container/fcd3ccd8eacf220c71d24703bfc69b26c6de12e4/pics/001-overview.png -------------------------------------------------------------------------------- /pics/040-Container-Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maeddes/java-and-container/fcd3ccd8eacf220c71d24703bfc69b26c6de12e4/pics/040-Container-Image.png -------------------------------------------------------------------------------- /pics/050-Dockerfile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maeddes/java-and-container/fcd3ccd8eacf220c71d24703bfc69b26c6de12e4/pics/050-Dockerfile.png -------------------------------------------------------------------------------- /pics/055-Dockerfile-Buildkit-parallel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maeddes/java-and-container/fcd3ccd8eacf220c71d24703bfc69b26c6de12e4/pics/055-Dockerfile-Buildkit-parallel.png -------------------------------------------------------------------------------- /pics/056-Dockerfile-MountCache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maeddes/java-and-container/fcd3ccd8eacf220c71d24703bfc69b26c6de12e4/pics/056-Dockerfile-MountCache.png -------------------------------------------------------------------------------- /pics/061-considerations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maeddes/java-and-container/fcd3ccd8eacf220c71d24703bfc69b26c6de12e4/pics/061-considerations.png -------------------------------------------------------------------------------- /pics/090-jib.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maeddes/java-and-container/fcd3ccd8eacf220c71d24703bfc69b26c6de12e4/pics/090-jib.png -------------------------------------------------------------------------------- /pics/104-buildpacks-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maeddes/java-and-container/fcd3ccd8eacf220c71d24703bfc69b26c6de12e4/pics/104-buildpacks-flow.png -------------------------------------------------------------------------------- /pics/108-paketo-springboot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maeddes/java-and-container/fcd3ccd8eacf220c71d24703bfc69b26c6de12e4/pics/108-paketo-springboot.png -------------------------------------------------------------------------------- /react/.npmrc: -------------------------------------------------------------------------------- 1 | @babel/core: 2 | node-options = --openssl-legacy-provider -------------------------------------------------------------------------------- /react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-todo-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^17.0.2", 7 | "react-dom": "^17.0.2", 8 | "react-scripts": "4.0.3" 9 | }, 10 | "scripts": { 11 | "start": "react-scripts --openssl-legacy-provider start", 12 | "build": "react-scripts --openssl-legacy-provider build", 13 | "test": "react-scripts --openssl-legacy-provider test", 14 | "eject": "react-scripts eject" 15 | }, 16 | "eslintConfig": { 17 | "extends": [ 18 | "react-app", 19 | "react-app/jest" 20 | ] 21 | }, 22 | "browserslist": { 23 | "production": [ 24 | ">0.2%", 25 | "not dead", 26 | "not op_mini all" 27 | ], 28 | "development": [ 29 | "last 1 chrome version", 30 | "last 1 firefox version", 31 | "last 1 safari version" 32 | ] 33 | } 34 | } -------------------------------------------------------------------------------- /react/project.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | [[build.env]] 3 | name = "NODE_ENV" 4 | value = "production" 5 | 6 | [run] 7 | port = 3000 8 | command = "npm run start" -------------------------------------------------------------------------------- /react/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | React Todo App 12 | 13 | 14 | 15 |
16 | 17 | -------------------------------------------------------------------------------- /react/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | max-width: 400px; 3 | margin: 0 auto; 4 | padding: 20px; 5 | font-family: Arial, sans-serif; 6 | } 7 | 8 | h1 { 9 | text-align: center; 10 | color: #333; 11 | } 12 | 13 | .todo-input { 14 | display: flex; 15 | margin-bottom: 20px; 16 | } 17 | 18 | .todo-input input { 19 | flex-grow: 1; 20 | padding: 10px; 21 | margin-right: 10px; 22 | border: 1px solid #ddd; 23 | border-radius: 4px; 24 | } 25 | 26 | .todo-input button { 27 | padding: 10px 15px; 28 | background-color: #4CAF50; 29 | color: white; 30 | border: none; 31 | border-radius: 4px; 32 | cursor: pointer; 33 | } 34 | 35 | .todo-list { 36 | list-style-type: none; 37 | padding: 0; 38 | } 39 | 40 | .todo-list li { 41 | display: flex; 42 | justify-content: space-between; 43 | align-items: center; 44 | padding: 10px; 45 | border-bottom: 1px solid #eee; 46 | } 47 | 48 | .todo-list li.completed span { 49 | text-decoration: line-through; 50 | color: #888; 51 | } 52 | 53 | .todo-list li button { 54 | background-color: #f44336; 55 | color: white; 56 | border: none; 57 | padding: 5px 10px; 58 | border-radius: 3px; 59 | cursor: pointer; 60 | } -------------------------------------------------------------------------------- /react/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import './App.css'; 3 | 4 | function App() { 5 | const [todos, setTodos] = useState([]); 6 | const [inputValue, setInputValue] = useState(''); 7 | 8 | const handleAddTodo = () => { 9 | if (inputValue.trim()) { 10 | setTodos([ 11 | ...todos, 12 | { 13 | id: Date.now(), 14 | text: inputValue.trim(), 15 | completed: false 16 | } 17 | ]); 18 | setInputValue(''); 19 | } 20 | }; 21 | 22 | const handleToggleTodo = (id) => { 23 | setTodos(todos.map(todo => 24 | todo.id === id ? { ...todo, completed: !todo.completed } : todo 25 | )); 26 | }; 27 | 28 | const handleDeleteTodo = (id) => { 29 | setTodos(todos.filter(todo => todo.id !== id)); 30 | }; 31 | 32 | return ( 33 |
34 |

Todo List

35 |
36 | setInputValue(e.target.value)} 40 | placeholder="Enter a new todo" 41 | /> 42 | 43 |
44 |
    45 | {todos.map(todo => ( 46 |
  • 50 | handleToggleTodo(todo.id)}> 51 | {todo.text} 52 | 53 | 56 |
  • 57 | ))} 58 |
59 |
60 | ); 61 | } 62 | 63 | export default App; -------------------------------------------------------------------------------- /react/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | background-color: #f4f4f4; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 13 | monospace; 14 | } -------------------------------------------------------------------------------- /react/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | ReactDOM.render( 7 | 8 | 9 | , 10 | document.getElementById('root') 11 | ); -------------------------------------------------------------------------------- /springboot/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /springboot/.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | import java.net.*; 17 | import java.io.*; 18 | import java.nio.channels.*; 19 | import java.util.Properties; 20 | 21 | public class MavenWrapperDownloader { 22 | 23 | private static final String WRAPPER_VERSION = "0.5.6"; 24 | /** 25 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 26 | */ 27 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 28 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 29 | 30 | /** 31 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 32 | * use instead of the default one. 33 | */ 34 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 35 | ".mvn/wrapper/maven-wrapper.properties"; 36 | 37 | /** 38 | * Path where the maven-wrapper.jar will be saved to. 39 | */ 40 | private static final String MAVEN_WRAPPER_JAR_PATH = 41 | ".mvn/wrapper/maven-wrapper.jar"; 42 | 43 | /** 44 | * Name of the property which should be used to override the default download url for the wrapper. 45 | */ 46 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 47 | 48 | public static void main(String args[]) { 49 | System.out.println("- Downloader started"); 50 | File baseDirectory = new File(args[0]); 51 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 52 | 53 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 54 | // wrapperUrl parameter. 55 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 56 | String url = DEFAULT_DOWNLOAD_URL; 57 | if(mavenWrapperPropertyFile.exists()) { 58 | FileInputStream mavenWrapperPropertyFileInputStream = null; 59 | try { 60 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 61 | Properties mavenWrapperProperties = new Properties(); 62 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 63 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 64 | } catch (IOException e) { 65 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 66 | } finally { 67 | try { 68 | if(mavenWrapperPropertyFileInputStream != null) { 69 | mavenWrapperPropertyFileInputStream.close(); 70 | } 71 | } catch (IOException e) { 72 | // Ignore ... 73 | } 74 | } 75 | } 76 | System.out.println("- Downloading from: " + url); 77 | 78 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 79 | if(!outputFile.getParentFile().exists()) { 80 | if(!outputFile.getParentFile().mkdirs()) { 81 | System.out.println( 82 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 83 | } 84 | } 85 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 86 | try { 87 | downloadFileFromURL(url, outputFile); 88 | System.out.println("Done"); 89 | System.exit(0); 90 | } catch (Throwable e) { 91 | System.out.println("- Error downloading"); 92 | e.printStackTrace(); 93 | System.exit(1); 94 | } 95 | } 96 | 97 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 98 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 99 | String username = System.getenv("MVNW_USERNAME"); 100 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 101 | Authenticator.setDefault(new Authenticator() { 102 | @Override 103 | protected PasswordAuthentication getPasswordAuthentication() { 104 | return new PasswordAuthentication(username, password); 105 | } 106 | }); 107 | } 108 | URL website = new URL(urlString); 109 | ReadableByteChannel rbc; 110 | rbc = Channels.newChannel(website.openStream()); 111 | FileOutputStream fos = new FileOutputStream(destination); 112 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 113 | fos.close(); 114 | rbc.close(); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /springboot/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /springboot/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/main/resources=UTF-8 4 | encoding//src/test/java=UTF-8 5 | encoding/=UTF-8 6 | -------------------------------------------------------------------------------- /springboot/.settings/org.eclipse.jdt.apt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.apt.aptEnabled=false 3 | -------------------------------------------------------------------------------- /springboot/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore 3 | org.eclipse.jdt.core.compiler.annotation.nonnull=org.springframework.lang.NonNull 4 | org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.springframework.lang.NonNullApi 5 | org.eclipse.jdt.core.compiler.annotation.nullable=org.springframework.lang.Nullable 6 | org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled 7 | org.eclipse.jdt.core.compiler.codegen.methodParameters=generate 8 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=21 9 | org.eclipse.jdt.core.compiler.compliance=21 10 | org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled 11 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 12 | org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=warning 13 | org.eclipse.jdt.core.compiler.problem.nullReference=warning 14 | org.eclipse.jdt.core.compiler.problem.nullSpecViolation=warning 15 | org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=ignore 16 | org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning 17 | org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore 18 | org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled 19 | org.eclipse.jdt.core.compiler.processAnnotations=disabled 20 | org.eclipse.jdt.core.compiler.release=enabled 21 | org.eclipse.jdt.core.compiler.source=21 22 | -------------------------------------------------------------------------------- /springboot/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /springboot/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "java.completion.enabled": false, 3 | "java.debug.settings.enableRunDebugCodeLens": false, 4 | "java.test.editor.enableShortcuts": false 5 | } -------------------------------------------------------------------------------- /springboot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM maven:3-eclipse-temurin-21 AS build 2 | RUN mkdir -p /opt/app/src 3 | COPY src /opt/app/src 4 | COPY pom.xml /opt/app 5 | RUN --mount=type=cache,target=/root/.m2 mvn -f /opt/app/pom.xml package 6 | 7 | FROM eclipse-temurin:21-jre 8 | COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 9 | ENTRYPOINT ["java","-jar","/opt/app.jar"] 10 | -------------------------------------------------------------------------------- /springboot/Dockerfile-jlink-alpine: -------------------------------------------------------------------------------- 1 | # Build the code in a maven-container 2 | FROM maven:3-eclipse-temurin-21 AS maven-build 3 | WORKDIR /opt/app 4 | COPY src ./src 5 | COPY pom.xml ./ 6 | RUN --mount=type=cache,target=/root/.m2 mvn package -DskipTests 7 | 8 | # Build the JRE directly in an Alpine container to avoid glibc/musl libc issues 9 | FROM eclipse-temurin:21-alpine AS jre-build 10 | WORKDIR /opt/app 11 | COPY --from=maven-build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar ./ 12 | RUN jar xf simplecode-0.0.1-SNAPSHOT.jar 13 | RUN jdeps --ignore-missing-deps -q \ 14 | --recursive \ 15 | --multi-release 21 \ 16 | --print-module-deps \ 17 | --class-path 'BOOT-INF/lib/*' \ 18 | simplecode-0.0.1-SNAPSHOT.jar > deps.info 19 | RUN jlink \ 20 | --verbose \ 21 | --add-modules $(cat deps.info) \ 22 | --strip-debug \ 23 | --compress 2 \ 24 | --no-header-files \ 25 | --no-man-pages \ 26 | --output /customjre 27 | 28 | FROM alpine:3.18 29 | COPY --from=jre-build /customjre /opt/jre 30 | ENV JAVA_HOME=/opt/jre 31 | ENV PATH="$PATH:$JAVA_HOME/bin" 32 | 33 | COPY --from=maven-build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 34 | ENTRYPOINT ["java","-jar","/opt/app.jar"] 35 | 36 | -------------------------------------------------------------------------------- /springboot/Dockerfile-jlink-bookworm: -------------------------------------------------------------------------------- 1 | 2 | FROM maven:3-eclipse-temurin-21 AS build 3 | WORKDIR /opt/app 4 | COPY src ./src 5 | COPY pom.xml ./ 6 | RUN --mount=type=cache,target=/root/.m2 mvn package -DskipTests 7 | RUN jar xf target/simplecode-0.0.1-SNAPSHOT.jar 8 | RUN jdeps --ignore-missing-deps -q \ 9 | --recursive \ 10 | --multi-release 21 \ 11 | --print-module-deps \ 12 | --class-path 'BOOT-INF/lib/*' \ 13 | target/*.jar > deps.info 14 | RUN jlink \ 15 | --verbose \ 16 | --add-modules $(cat deps.info) \ 17 | --strip-debug \ 18 | --compress 2 \ 19 | --no-header-files \ 20 | --no-man-pages \ 21 | --output /customjre 22 | 23 | FROM debian:bookworm-slim 24 | COPY --from=build /customjre /opt/jre 25 | ENV JAVA_HOME=/opt/jre 26 | ENV PATH="$PATH:$JAVA_HOME/bin" 27 | 28 | COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 29 | ENTRYPOINT ["java","-jar","/opt/app.jar"] 30 | -------------------------------------------------------------------------------- /springboot/Dockerfile-multistage-builder: -------------------------------------------------------------------------------- 1 | FROM maven:3-eclipse-temurin-21 AS build 2 | WORKDIR /opt/app 3 | COPY src ./src 4 | COPY pom.xml . 5 | RUN mvn -f /opt/app/pom.xml package -DskipTests 6 | 7 | FROM eclipse-temurin:21-jre 8 | COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 9 | ENTRYPOINT ["java","-jar","/opt/app.jar"] 10 | 11 | 12 | -------------------------------------------------------------------------------- /springboot/Dockerfile-multistage-cache: -------------------------------------------------------------------------------- 1 | FROM maven:3-eclipse-temurin-21 AS build 2 | WORKDIR /opt/app 3 | COPY src ./src 4 | COPY pom.xml . 5 | RUN --mount=type=cache,target=/root/.m2 mvn -f /opt/app/pom.xml package 6 | 7 | FROM eclipse-temurin:21-jre 8 | RUN mkdir -p /opt/app 9 | COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 10 | ENTRYPOINT ["java","-jar","/opt/app.jar"] 11 | -------------------------------------------------------------------------------- /springboot/Dockerfile-multistage-layered: -------------------------------------------------------------------------------- 1 | FROM maven:3-eclipse-temurin-21 AS maven 2 | WORKDIR /opt/app 3 | COPY src ./src 4 | COPY pom.xml . 5 | RUN --mount=type=cache,target=/root/.m2 mvn -f /opt/app/pom.xml package -DskipTests 6 | 7 | FROM eclipse-temurin:21-jre AS builder 8 | WORKDIR /opt/app 9 | COPY --from=maven /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar application.jar 10 | RUN java -Djarmode=layertools -jar application.jar extract 11 | 12 | FROM eclipse-temurin:21-jre 13 | WORKDIR /application 14 | COPY --from=builder /opt/app/dependencies/ ./ 15 | COPY --from=builder /opt/app/spring-boot-loader/ ./ 16 | COPY --from=builder /opt/app/snapshot-dependencies/ ./ 17 | COPY --from=builder /opt/app/application/ ./ 18 | ENTRYPOINT ["java","org.springframework.boot.loader.launch.JarLauncher"] 19 | -------------------------------------------------------------------------------- /springboot/Dockerfile-multistage-layered-jvm-flags: -------------------------------------------------------------------------------- 1 | FROM maven:3-eclipse-temurin-21 AS maven 2 | RUN mkdir -p /opt/app/src 3 | COPY src /opt/app/src 4 | COPY pom.xml /opt/app 5 | RUN --mount=type=cache,target=/root/.m2 mvn -f /opt/app/pom.xml package 6 | 7 | FROM eclipse-temurin:21-jre AS builder 8 | WORKDIR /application 9 | COPY --from=maven /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar application.jar 10 | RUN java -Djarmode=layertools -jar application.jar extract 11 | 12 | FROM eclipse-temurin:21-jre 13 | WORKDIR /application 14 | COPY --from=builder /application/dependencies/ ./ 15 | COPY --from=builder /application/spring-boot-loader/ ./ 16 | COPY --from=builder /application/snapshot-dependencies/ ./ 17 | COPY --from=builder /application/application/ ./ 18 | ENTRYPOINT ["java","-XX:+UseParallelGC","-XX:MaxRAMPercentage=75","org.springframework.boot.loader.launch.JarLauncher"] 19 | 20 | -------------------------------------------------------------------------------- /springboot/Dockerfile-multistage-layered-otel-agent: -------------------------------------------------------------------------------- 1 | FROM maven:3-eclipse-temurin-21 AS maven 2 | WORKDIR /opt/app 3 | COPY src ./src 4 | COPY pom.xml ./ 5 | RUN --mount=type=cache,target=/root/.m2 mvn -f /opt/app/pom.xml package -DskipTests 6 | 7 | FROM eclipse-temurin:21-jre AS builder 8 | WORKDIR /opt/app 9 | COPY --from=maven /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar application.jar 10 | RUN java -Djarmode=layertools -jar application.jar extract 11 | 12 | FROM eclipse-temurin:21-jre 13 | WORKDIR /opt/app 14 | COPY --from=builder /opt/app/dependencies/ ./ 15 | COPY --from=builder /opt/app/spring-boot-loader/ ./ 16 | COPY --from=builder /opt/app/snapshot-dependencies/ ./ 17 | COPY --from=builder /opt/app/application/ ./ 18 | 19 | # Set OpenTelemetry agent as Java agent 20 | ENV JAVA_TOOL_OPTIONS="-javaagent:/opt/app/opentelemetry-javaagent.jar" 21 | ENV OTEL_SERVICE_NAME="java-application" 22 | ENV OTEL_TRACES_EXPORTER="otlp" 23 | ENV OTEL_METRICS_EXPORTER="otlp" 24 | ENV OTEL_LOGS_EXPORTER="otlp" 25 | 26 | ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar ./ 27 | 28 | ENTRYPOINT ["java","org.springframework.boot.loader.launch.JarLauncher"] 29 | #ENTRYPOINT ["java","-javaagent:/opt/app/opentelemetry-javaagent.jar","org.springframework.boot.loader.launch.JarLauncher"] 30 | -------------------------------------------------------------------------------- /springboot/Dockerfile-new-user: -------------------------------------------------------------------------------- 1 | FROM maven:3-eclipse-temurin-21 AS build 2 | RUN mkdir -p /opt/app/src 3 | COPY src /opt/app/src 4 | COPY pom.xml /opt/app 5 | RUN --mount=type=cache,target=/root/.m2 mvn -f /opt/app/pom.xml package 6 | # RUN mvn -f /opt/app/pom.xml clean package 7 | 8 | FROM eclipse-temurin:21-jre 9 | RUN useradd -ms /bin/bash newuser 10 | USER newuser 11 | COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 12 | ENTRYPOINT ["java","-jar","/opt/app.jar"] 13 | -------------------------------------------------------------------------------- /springboot/Dockerfile-simple-adoptopenjdk-11: -------------------------------------------------------------------------------- 1 | FROM adoptopenjdk:11-jre-hotspot 2 | COPY target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 3 | ENTRYPOINT ["java", "-jar", "/opt/app.jar"] 4 | -------------------------------------------------------------------------------- /springboot/Dockerfile-simple-ibm-semeru: -------------------------------------------------------------------------------- 1 | FROM ibm-semeru-runtimes:open-21-jre 2 | COPY target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 3 | ENTRYPOINT ["java", "-jar", "/opt/app.jar"] 4 | -------------------------------------------------------------------------------- /springboot/Dockerfile-simple-temurin: -------------------------------------------------------------------------------- 1 | FROM eclipse-temurin:21-jre 2 | COPY target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 3 | ENTRYPOINT ["java", "-jar", "/opt/app.jar"] 4 | -------------------------------------------------------------------------------- /springboot/Dockerfile-simple-temurin-JVMflags: -------------------------------------------------------------------------------- 1 | FROM eclipse-temurin:21-jre 2 | COPY target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 3 | ENTRYPOINT ["java","-XX:+UseParallelGC","-XX:MaxRAMPercentage=75","-jar", "/opt/app.jar"] 4 | -------------------------------------------------------------------------------- /springboot/Dockerfile-simple-ubuntu: -------------------------------------------------------------------------------- 1 | FROM ubuntu:24.04 2 | RUN apt update 3 | RUN apt install openjdk-21-jre-headless -y 4 | COPY target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 5 | ENTRYPOINT ["java","-jar","/opt/app.jar"] 6 | 7 | -------------------------------------------------------------------------------- /springboot/Dockerfile-ultimate: -------------------------------------------------------------------------------- 1 | FROM maven:3-eclipse-temurin-21 AS build 2 | WORKDIR /opt/app 3 | COPY src ./src 4 | COPY pom.xml . 5 | RUN --mount=type=cache,target=/root/.m2 mvn package -DskipTests 6 | RUN jar xf target/simplecode-0.0.1-SNAPSHOT.jar 7 | RUN jdeps --ignore-missing-deps -q \ 8 | --recursive \ 9 | --multi-release 21 \ 10 | --print-module-deps \ 11 | --class-path 'BOOT-INF/lib/*' \ 12 | target/*.jar > deps.info 13 | RUN jlink \ 14 | --verbose \ 15 | --add-modules $(cat deps.info) \ 16 | --strip-debug \ 17 | --compress 2 \ 18 | --no-header-files \ 19 | --no-man-pages \ 20 | --output /customjre 21 | 22 | FROM eclipse-temurin:21-jre AS extractor 23 | WORKDIR /opt/app 24 | COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar application.jar 25 | RUN java -Djarmode=layertools -jar application.jar extract 26 | 27 | FROM ubuntu:jammy 28 | ENV JAVA_HOME=/opt/java/jdk21 29 | ENV PATH=$JAVA_HOME/bin:$PATH 30 | COPY --from=build /customjre $JAVA_HOME 31 | WORKDIR /opt/app 32 | COPY --from=extractor /opt/app/dependencies/ ./ 33 | COPY --from=extractor /opt/app/spring-boot-loader/ ./ 34 | COPY --from=extractor /opt/app/snapshot-dependencies/ ./ 35 | COPY --from=extractor /opt/app/application/ ./ 36 | RUN groupadd -r appuser && useradd -r -g appuser appuser 37 | RUN chown -R appuser:appuser /opt/app 38 | USER appuser 39 | 40 | ENTRYPOINT ["java","-XX:+UseParallelGC","-XX:MaxRAMPercentage=75","org.springframework.boot.loader.launch.JarLauncher"] -------------------------------------------------------------------------------- /springboot/build/bootJarMainClassName: -------------------------------------------------------------------------------- 1 | de.maeddes.simplecode.SimplecodeApplication -------------------------------------------------------------------------------- /springboot/build/bootRunMainClassName: -------------------------------------------------------------------------------- 1 | de.maeddes.simplecode.SimplecodeApplication -------------------------------------------------------------------------------- /springboot/build/resources/main/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /springboot/build/tmp/bootJar/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: org.springframework.boot.loader.JarLauncher 3 | Start-Class: de.maeddes.simplecode.SimplecodeApplication 4 | Spring-Boot-Version: 2.5.2 5 | Spring-Boot-Classes: BOOT-INF/classes/ 6 | Spring-Boot-Lib: BOOT-INF/lib/ 7 | Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx 8 | Spring-Boot-Layers-Index: BOOT-INF/layers.idx 9 | 10 | -------------------------------------------------------------------------------- /springboot/build/tmp/compileJava/source-classes-mapping.txt: -------------------------------------------------------------------------------- 1 | de/maeddes/simplecode/SimplecodeApplication.java 2 | de.maeddes.simplecode.SimplecodeApplication 3 | -------------------------------------------------------------------------------- /springboot/buildAll.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | LOG_FILE="container_build.log" 4 | echo "🚀 Starting Docker builds..." > "$LOG_FILE" 5 | echo "Build started at: $(date)" >> "$LOG_FILE" 6 | echo "---------------------------------" >> "$LOG_FILE" 7 | 8 | # Loop through each Dockerfile 9 | for file in Dockerfile*; do 10 | tag=${file#Dockerfile} 11 | tag=${tag#-} 12 | [[ -z "$tag" ]] && tag="default" 13 | 14 | echo "🔧 Building Docker image with tag: $tag" 15 | echo "Building $file as java-image:$tag" >> "$LOG_FILE" 16 | 17 | if docker build -f "$file" -t "java-image:$tag" .; then 18 | echo "✅ SUCCESS: $file built as java-image:$tag" >> "$LOG_FILE" 19 | else 20 | echo "❌ FAILURE: $file failed to build" >> "$LOG_FILE" 21 | fi 22 | 23 | echo "---------------------------------" >> "$LOG_FILE" 24 | done 25 | 26 | # Add a final summary of built images to the log file 27 | echo "📦 Final Docker images list:" >> "$LOG_FILE" 28 | docker images >> "$LOG_FILE" 29 | 30 | echo "✅ Build process completed. Check $LOG_FILE for details." 31 | 32 | -------------------------------------------------------------------------------- /springboot/buildpacks.yml: -------------------------------------------------------------------------------- 1 | # doesn't work this way 2 | paketo-buildpacks/maven: 3 | version: 5.2.0 4 | 5 | -------------------------------------------------------------------------------- /springboot/gradlex/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /springboot/gradlex/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | arguments=--init-script /home/vscode/.vscode-server/data/User/globalStorage/redhat.java/1.40.0/config_linux/org.eclipse.osgi/58/0/.cp/gradle/init/init.gradle --init-script /home/vscode/.vscode-server/data/User/globalStorage/redhat.java/1.40.0/config_linux/org.eclipse.osgi/58/0/.cp/gradle/protobuf/init.gradle 2 | auto.sync=true 3 | build.scans.enabled=false 4 | connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) 5 | connection.project.dir= 6 | eclipse.preferences.version=1 7 | gradle.user.home= 8 | java.home=/usr/local/sdkman/candidates/java/current 9 | jvm.arguments= 10 | offline.mode=false 11 | override.workspace.settings=true 12 | show.console.view=true 13 | show.executions.view=true 14 | -------------------------------------------------------------------------------- /springboot/gradlex/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | */ 4 | 5 | plugins { 6 | id 'org.springframework.boot' version '2.5.2' 7 | id 'io.spring.dependency-management' version '1.0.11.RELEASE' 8 | id 'java' 9 | } 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'org.springframework.boot:spring-boot-starter-actuator' 17 | implementation 'org.springframework.boot:spring-boot-starter-web' 18 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 19 | } 20 | 21 | group = 'de.maeddes' 22 | version = '0.0.1-SNAPSHOT' 23 | description = 'simplecode' 24 | sourceCompatibility = '11' 25 | 26 | test { 27 | useJUnitPlatform() 28 | } 29 | -------------------------------------------------------------------------------- /springboot/gradlex/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Mar 24 16:18:21 UTC 2025 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /springboot/gradlex/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /springboot/gradlex/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /springboot/gradlex/settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | */ 4 | 5 | rootProject.name = 'simplecode' 6 | -------------------------------------------------------------------------------- /springboot/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | fi 118 | 119 | if [ -z "$JAVA_HOME" ]; then 120 | javaExecutable="`which javac`" 121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 122 | # readlink(1) is not available as standard on Solaris 10. 123 | readLink=`which readlink` 124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 125 | if $darwin ; then 126 | javaHome="`dirname \"$javaExecutable\"`" 127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 128 | else 129 | javaExecutable="`readlink -f \"$javaExecutable\"`" 130 | fi 131 | javaHome="`dirname \"$javaExecutable\"`" 132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 133 | JAVA_HOME="$javaHome" 134 | export JAVA_HOME 135 | fi 136 | fi 137 | fi 138 | 139 | if [ -z "$JAVACMD" ] ; then 140 | if [ -n "$JAVA_HOME" ] ; then 141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 142 | # IBM's JDK on AIX uses strange locations for the executables 143 | JAVACMD="$JAVA_HOME/jre/sh/java" 144 | else 145 | JAVACMD="$JAVA_HOME/bin/java" 146 | fi 147 | else 148 | JAVACMD="`which java`" 149 | fi 150 | fi 151 | 152 | if [ ! -x "$JAVACMD" ] ; then 153 | echo "Error: JAVA_HOME is not defined correctly." >&2 154 | echo " We cannot execute $JAVACMD" >&2 155 | exit 1 156 | fi 157 | 158 | if [ -z "$JAVA_HOME" ] ; then 159 | echo "Warning: JAVA_HOME environment variable is not set." 160 | fi 161 | 162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 163 | 164 | # traverses directory structure from process work directory to filesystem root 165 | # first directory with .mvn subdirectory is considered project base directory 166 | find_maven_basedir() { 167 | 168 | if [ -z "$1" ] 169 | then 170 | echo "Path not specified to find_maven_basedir" 171 | return 1 172 | fi 173 | 174 | basedir="$1" 175 | wdir="$1" 176 | while [ "$wdir" != '/' ] ; do 177 | if [ -d "$wdir"/.mvn ] ; then 178 | basedir=$wdir 179 | break 180 | fi 181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 182 | if [ -d "${wdir}" ]; then 183 | wdir=`cd "$wdir/.."; pwd` 184 | fi 185 | # end of workaround 186 | done 187 | echo "${basedir}" 188 | } 189 | 190 | # concatenates all lines of a file 191 | concat_lines() { 192 | if [ -f "$1" ]; then 193 | echo "$(tr -s '\n' ' ' < "$1")" 194 | fi 195 | } 196 | 197 | BASE_DIR=`find_maven_basedir "$(pwd)"` 198 | if [ -z "$BASE_DIR" ]; then 199 | exit 1; 200 | fi 201 | 202 | ########################################################################################## 203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 204 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 205 | ########################################################################################## 206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 207 | if [ "$MVNW_VERBOSE" = true ]; then 208 | echo "Found .mvn/wrapper/maven-wrapper.jar" 209 | fi 210 | else 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 213 | fi 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 216 | else 217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 218 | fi 219 | while IFS="=" read key value; do 220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 221 | esac 222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 223 | if [ "$MVNW_VERBOSE" = true ]; then 224 | echo "Downloading from: $jarUrl" 225 | fi 226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 227 | if $cygwin; then 228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 229 | fi 230 | 231 | if command -v wget > /dev/null; then 232 | if [ "$MVNW_VERBOSE" = true ]; then 233 | echo "Found wget ... using wget" 234 | fi 235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 236 | wget "$jarUrl" -O "$wrapperJarPath" 237 | else 238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 239 | fi 240 | elif command -v curl > /dev/null; then 241 | if [ "$MVNW_VERBOSE" = true ]; then 242 | echo "Found curl ... using curl" 243 | fi 244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 245 | curl -o "$wrapperJarPath" "$jarUrl" -f 246 | else 247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 248 | fi 249 | 250 | else 251 | if [ "$MVNW_VERBOSE" = true ]; then 252 | echo "Falling back to using Java to download" 253 | fi 254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 255 | # For Cygwin, switch paths to Windows format before running javac 256 | if $cygwin; then 257 | javaClass=`cygpath --path --windows "$javaClass"` 258 | fi 259 | if [ -e "$javaClass" ]; then 260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 261 | if [ "$MVNW_VERBOSE" = true ]; then 262 | echo " - Compiling MavenWrapperDownloader.java ..." 263 | fi 264 | # Compiling the Java class 265 | ("$JAVA_HOME/bin/javac" "$javaClass") 266 | fi 267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 268 | # Running the downloader 269 | if [ "$MVNW_VERBOSE" = true ]; then 270 | echo " - Running MavenWrapperDownloader.java ..." 271 | fi 272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 273 | fi 274 | fi 275 | fi 276 | fi 277 | ########################################################################################## 278 | # End of extension 279 | ########################################################################################## 280 | 281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 282 | if [ "$MVNW_VERBOSE" = true ]; then 283 | echo $MAVEN_PROJECTBASEDIR 284 | fi 285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 286 | 287 | # For Cygwin, switch paths to Windows format before running java 288 | if $cygwin; then 289 | [ -n "$M2_HOME" ] && 290 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 291 | [ -n "$JAVA_HOME" ] && 292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 293 | [ -n "$CLASSPATH" ] && 294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 295 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 297 | fi 298 | 299 | # Provide a "standardized" way to retrieve the CLI args that will 300 | # work with both Windows and non-Windows executions. 301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 302 | export MAVEN_CMD_LINE_ARGS 303 | 304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 305 | 306 | exec "$JAVACMD" \ 307 | $MAVEN_OPTS \ 308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 311 | -------------------------------------------------------------------------------- /springboot/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 124 | 125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 162 | if ERRORLEVEL 1 goto error 163 | goto end 164 | 165 | :error 166 | set ERROR_CODE=1 167 | 168 | :end 169 | @endlocal & set ERROR_CODE=%ERROR_CODE% 170 | 171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 175 | :skipRcPost 176 | 177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 179 | 180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 181 | 182 | exit /B %ERROR_CODE% 183 | -------------------------------------------------------------------------------- /springboot/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 3.4.1 9 | 10 | 11 | de.maeddes 12 | simplecode 13 | 0.0.1-SNAPSHOT 14 | simplecode 15 | Demo project for Spring Boot 16 | 17 | 18 | 21 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-actuator 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-web 29 | 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-test 34 | test 35 | 36 | 37 | org.junit.vintage 38 | junit-vintage-engine 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-maven-plugin 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /springboot/runAll.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Configuration 4 | LOG_FILE="container_run.log" 5 | TEST_DURATION=5 # in seconds 6 | TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') 7 | 8 | # Initialize log file 9 | echo "Docker Image Tests - Started at $TIMESTAMP" > "$LOG_FILE" 10 | echo "----------------------------------------" >> "$LOG_FILE" 11 | 12 | # Get all Docker images (excluding intermediary images) 13 | images=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "") 14 | 15 | # Check if any images exist 16 | if [ -z "$images" ]; then 17 | echo "No Docker images found." | tee -a "$LOG_FILE" 18 | exit 1 19 | fi 20 | 21 | # Count the number of images 22 | image_count=$(echo "$images" | wc -l) 23 | echo "Found $image_count Docker images to test." | tee -a "$LOG_FILE" 24 | echo "" >> "$LOG_FILE" 25 | 26 | # Function to test an image and log results 27 | test_image() { 28 | local image="$1" 29 | echo "Testing image: $image" | tee -a "$LOG_FILE" 30 | 31 | # Start container with a timeout 32 | echo " Starting container..." | tee -a "$LOG_FILE" 33 | container_id=$(docker run -d "$image") 34 | 35 | if [ $? -ne 0 ]; then 36 | echo " ❌ FAILED: Could not start container for image $image" | tee -a "$LOG_FILE" 37 | echo "----------------------------------------" >> "$LOG_FILE" 38 | return 1 39 | fi 40 | 41 | echo " Container ID: $container_id" >> "$LOG_FILE" 42 | echo " Running for $TEST_DURATION seconds..." | tee -a "$LOG_FILE" 43 | 44 | # Wait for the specified duration 45 | sleep "$TEST_DURATION" 46 | 47 | # Check if container is still running 48 | if docker ps -q --filter "id=$container_id" | grep -q .; then 49 | container_status="Still running after $TEST_DURATION seconds" 50 | exit_code="N/A" 51 | else 52 | container_status="Exited before $TEST_DURATION seconds timeout" 53 | exit_code=$(docker inspect "$container_id" --format='{{.State.ExitCode}}') 54 | fi 55 | 56 | # Capture logs 57 | echo " Container logs:" | tee -a "$LOG_FILE" 58 | docker logs "$container_id" 2>&1 | tee -a "$LOG_FILE" 59 | 60 | # Stop and remove container 61 | docker stop "$container_id" >/dev/null 62 | docker rm "$container_id" >/dev/null 63 | 64 | # Log results 65 | echo " Status: $container_status" | tee -a "$LOG_FILE" 66 | 67 | if [ "$exit_code" = "N/A" ]; then 68 | echo " Exit code: N/A (container was still running)" | tee -a "$LOG_FILE" 69 | echo " ✅ PASSED: Container stayed running for the full duration" | tee -a "$LOG_FILE" 70 | elif [ "$exit_code" = "0" ]; then 71 | echo " Exit code: 0" | tee -a "$LOG_FILE" 72 | echo " ✅ PASSED: Container exited with code 0" | tee -a "$LOG_FILE" 73 | else 74 | echo " Exit code: $exit_code" | tee -a "$LOG_FILE" 75 | echo " ❌ FAILED: Container exited with non-zero code" | tee -a "$LOG_FILE" 76 | fi 77 | 78 | echo "----------------------------------------" >> "$LOG_FILE" 79 | } 80 | 81 | # Test each image 82 | count=1 83 | for image in $images; do 84 | echo "[$count/$image_count] Testing $image" 85 | test_image "$image" 86 | ((count++)) 87 | echo "" | tee -a "$LOG_FILE" 88 | done 89 | 90 | # Finalize log file 91 | FINISH_TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S') 92 | echo "Docker Image Tests - Completed at $FINISH_TIMESTAMP" >> "$LOG_FILE" 93 | echo "All tests completed. Results saved to $LOG_FILE" -------------------------------------------------------------------------------- /springboot/src/main/java/de/maeddes/simplecode/SimplecodeApplication.java: -------------------------------------------------------------------------------- 1 | package de.maeddes.simplecode; 2 | 3 | import org.slf4j.LoggerFactory; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | @SpringBootApplication 11 | @RestController 12 | public class SimplecodeApplication { 13 | 14 | @Value("${HOSTNAME:not_set}") 15 | String hostname; 16 | 17 | @Value("${spring.profiles.active: none}") 18 | String profile; 19 | 20 | org.slf4j.Logger logger = LoggerFactory.getLogger(SimplecodeApplication.class); 21 | 22 | private String getHostname(){ 23 | 24 | if(!hostname.equals("not_set")) return hostname; 25 | return "probably not set"; 26 | 27 | } 28 | 29 | @GetMapping("/") 30 | String helloABC(){ 31 | 32 | logger.info("Call to hello method on instance: " + getHostname()); 33 | return " Hello, Container people ! "; 34 | 35 | } 36 | 37 | public static void main(final String[] args) { 38 | SpringApplication.run(SimplecodeApplication.class, args); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /springboot/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /springboot/src/test/java/de/maeddes/simplecode/SimplecodeApplicationTests.java: -------------------------------------------------------------------------------- 1 | package de.maeddes.simplecode; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SimplecodeApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /stuff/Dockerfile-bellsoft: -------------------------------------------------------------------------------- 1 | FROM alpine:3.11 as liberica 2 | 3 | ### Modify argument LIBERICA_IMAGE_VARIANT or redefine it via --build-arg parameter to have specific liberica image installed: 4 | ### docker build . --build-arg LIBERICA_IMAGE_VARIANT=[standard|lite|base] 5 | ### base: minimal image with compressed java.base module, Server VM and optional files stripped, ~37 MB with Alpine base 6 | ### lite: lite image with minimal footprint and Server VM, ~ 100 MB 7 | ### standard: standard jdk image with Server VM and jmods, can be used to create arbirary module set, ~180 MB 8 | 9 | ENV LANG=en_US.UTF-8 \ 10 | LANGUAGE=en_US:en 11 | # LC_ALL=en_US.UTF-8 12 | 13 | ARG LIBERICA_IMAGE_VARIANT=lite 14 | 15 | ARG LIBERICA_JVM_DIR=/usr/lib/jvm 16 | ARG LIBERICA_ROOT=${LIBERICA_JVM_DIR}/jdk-15.0.2-bellsoft 17 | ARG LIBERICA_VERSION=15.0.2 18 | ARG LIBERICA_BUILD=10 19 | ARG LIBERICA_VARIANT=jdk 20 | ARG LIBERICA_RELEASE_TAG= 21 | ARG LIBERICA_ARCH=x64 22 | ARG LIBERICA_GLIBC=no 23 | 24 | ARG OPT_PKGS= 25 | 26 | RUN RTAG="$LIBERICA_RELEASE_TAG" && if [ "x${RTAG}" = "x" ]; then RTAG="$LIBERICA_VERSION"; fi && \ 27 | RSUFFIX="" && if [ "$LIBERICA_IMAGE_VARIANT" = "lite" ]; then RSUFFIX="-lite"; fi && \ 28 | LIBSUFFIX="" && if [ "$LIBERICA_GLIBC" = "no" ]; then LIBSUFFIX="-musl"; fi && \ 29 | for pkg in $OPT_PKGS ; do apk --no-cache add $pkg ; done && \ 30 | mkdir -p /tmp/java && \ 31 | LIBERICA_BUILD_STR=${LIBERICA_BUILD:+"+${LIBERICA_BUILD}"} && \ 32 | PKG=`echo "bellsoft-${LIBERICA_VARIANT}${LIBERICA_VERSION}${LIBERICA_BUILD_STR}-linux-${LIBERICA_ARCH}${LIBSUFFIX}${RSUFFIX}.tar.gz"` && \ 33 | PKG_URL="https://download.bell-sw.com/java/${LIBERICA_VERSION}${LIBERICA_BUILD_STR}/${PKG}" && \ 34 | echo "Download ${PKG_URL}" && \ 35 | wget "${PKG_URL}" -O /tmp/java/jdk.tar.gz && \ 36 | SHA1=`wget -q "https://download.bell-sw.com/sha1sum/java/${LIBERICA_VERSION}${LIBERICA_BUILD_STR}" -O - | grep ${PKG} | cut -f1 -d' '` && \ 37 | echo "${SHA1} */tmp/java/jdk.tar.gz" | sha1sum -c - && \ 38 | tar xzf /tmp/java/jdk.tar.gz -C /tmp/java && \ 39 | UNPACKED_ROOT="/tmp/java/${LIBERICA_VARIANT}-${LIBERICA_VERSION}" && \ 40 | case $LIBERICA_IMAGE_VARIANT in \ 41 | base) apk add binutils && mkdir -pv "${LIBERICA_JVM_DIR}" && "${UNPACKED_ROOT}/bin/jlink" --add-modules java.base --compress=2 --no-header-files --no-man-pages --strip-debug --module-path \ 42 | "${UNPACKED_ROOT}"/jmods --vm=server --output "${LIBERICA_ROOT}" && apk del binutils ;; \ 43 | standard) apk --no-cache add binutils && mkdir -pv "${LIBERICA_ROOT}" && find /tmp/java/${LIBERICA_VARIANT}* -maxdepth 1 -mindepth 1 -exec mv -v "{}" "${LIBERICA_ROOT}/" \; ;; \ 44 | *) mkdir -pv "${LIBERICA_ROOT}" && find /tmp/java/${LIBERICA_VARIANT}* -maxdepth 1 -mindepth 1 -exec mv -v "{}" "${LIBERICA_ROOT}/" \; ;; \ 45 | esac && \ 46 | ln -s $LIBERICA_ROOT /usr/lib/jvm/jdk && \ 47 | rm -rf /tmp/java && rm -rf /tmp/hsperfdata_root 48 | 49 | ENV JAVA_HOME=${LIBERICA_ROOT} \ 50 | PATH=${LIBERICA_ROOT}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 51 | 52 | -------------------------------------------------------------------------------- /stuff/Dockerfile-multistage-experimental-cache: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:experimental 2 | FROM maven:3-eclipse-temurin-17 AS build 3 | RUN mkdir -p /opt/app/src 4 | COPY src /opt/app/src 5 | COPY pom.xml /opt/app 6 | RUN --mount=type=cache,target=/root/.m2 mvn -f /opt/app/pom.xml clean package 7 | 8 | FROM eclipse-temurin:17-jre 9 | RUN mkdir -p /opt/app 10 | COPY --from=build /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 11 | CMD ["java","-jar","/opt/app.jar"] 12 | -------------------------------------------------------------------------------- /stuff/Dockerfile-s2i: -------------------------------------------------------------------------------- 1 | FROM docker.io/fabric8/s2i-java 2 | LABEL "io.openshift.s2i.scripts-url"="image:///usr/local/s2i" \ 3 | "io.openshift.s2i.destination"="/tmp" \ 4 | "io.openshift.s2i.build.image"="docker.io/fabric8/s2i-java" 5 | 6 | USER root 7 | # Copying in source code 8 | COPY upload/src /tmp/src 9 | # Change file ownership to the assemble user. Builder image must support chown command. 10 | RUN chown -R 1001:0 /tmp/src 11 | USER 1001 12 | # Assemble script sourced from builder image based on user input or image metadata. 13 | # If this file does not exist in the image, the build will fail. 14 | RUN /usr/local/s2i/assemble 15 | # Run script sourced from builder image based on user input or image metadata. 16 | # If this file does not exist in the image, the build will fail. 17 | CMD /usr/local/s2i/run 18 | -------------------------------------------------------------------------------- /stuff/braindump: -------------------------------------------------------------------------------- 1 | What is the best Java base image? 2 | (Define "best", "simplified", "right abstraction to complexity") 3 | 4 | - https://pkgs.alpinelinux.org/package/edge/community/x86/openjdk8-jre 5 | - https://hub.docker.com/_/openjdk 6 | - https://hub.docker.com/_/amazoncorretto 7 | - https://hub.docker.com/_/microsoft-java-jre 8 | - https://hub.docker.com/u/bellsoft 9 | 10 | Option - manual build with commits 11 | 12 | images: 13 | ubuntu:20.10 14 | 15 | export DOCKER_BUILDKIT=0 16 | 17 | Alternative 1: 18 | 19 | docker run -it ubuntu:20.10 /bin/bash 20 | apt update 21 | apt install default-jre -y || apt install openjdk-11-jre-headless -y || apt install openjdk-11-jre -y 22 | exit 23 | docker commit $(docker ps -lq) maeddes/java-base 24 | 25 | (https://serverfault.com/questions/949991/how-to-install-tzdata-on-a-ubuntu-docker-image) 26 | 27 | Alternative 2: 28 | 29 | docker run ubuntu:20.10 bash -c "apt update && apt install openjdk-11-jre-headless -y" 30 | (Not working: docker run ubuntu:21.04 bash -c "apt update && apt install openjdk-11-jre-headless -y") 31 | docker commit --change='CMD ["/bin/bash"]' $(docker ps -lq) maeddes/java-base 32 | 33 | docker run maeddes/java-base 34 | 35 | docker cp target/simplecode-0.0.1-SNAPSHOT.jar $(docker ps -lq):/opt/app.jar 36 | 37 | docker commit --change='CMD ["java","-jar","/opt/app.jar"]' $(docker ps -lq) maeddes/java-app 38 | 39 | docker history maeddes/java-base 40 | docker history maeddes/java-app 41 | 42 | dive maeddes/java-base 43 | dive maeddes/java-app 44 | 45 | Ctrl + Space: doesn't work -> vi ~/.dive.yaml 46 | Ctrl + A Filetree view: show/hide added files 47 | Ctrl + R Filetree view: show/hide removed files 48 | Ctrl + M Filetree view: show/hide modified files 49 | Ctrl + U Filetree view: show/hide unmodified files <- 50 | 51 | docker run -p 8080:8080 maeddes/java-app java -jar /tmp/simplecode-0.0.1-SNAPSHOT.jar 52 | 53 | First dockerfile: 54 | 55 | FROM ubuntu:20.10 56 | RUN apt update && apt install openjdk-11-jre-headless -y 57 | COPY target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 58 | CMD ["java","-jar","/opt/app.jar"] 59 | 60 | docker build -f- .< 112 | 113 | 114 | org.springframework.boot 115 | spring-boot-maven-plugin 116 | 117 | 118 | true 119 | 120 | 121 | 122 | 123 | 124 | 125 | FROM maven:3.6.3-jdk-11 AS maven 126 | RUN mkdir -p /opt/app/src 127 | COPY src /opt/app/src 128 | COPY pom.xml /opt/app 129 | RUN mvn -f /opt/app/pom.xml clean package 130 | 131 | FROM adoptopenjdk:11-jre-hotspot as builder 132 | WORKDIR application 133 | COPY --from=maven /opt/app/target/simplecode-0.0.1-SNAPSHOT.jar application.jar 134 | RUN java -Djarmode=layertools -jar application.jar extract 135 | 136 | FROM adoptopenjdk:11-jre-hotspot 137 | WORKDIR application 138 | COPY --from=builder application/dependencies/ ./ 139 | COPY --from=builder application/spring-boot-loader/ ./ 140 | COPY --from=builder application/snapshot-dependencies/ ./ 141 | COPY --from=builder application/application/ ./ 142 | ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] 143 | 144 | not working: 145 | BP_GRADLE_BUILT_ARTIFACT=/workspace/build/libs/simplecode-0.1-all.jar pack --env BP_GRADLE_BUILT_ARTIFACT build maeddes/micronaut-app:paketo 146 | 147 | 148 | Sources: 149 | https://www.heise.de/hintergrund/Container-Images-Abschied-vom-Dockerfile-5997535.html 150 | https://blog.codecentric.de/en/2020/11/buildpacks-spring-boot/ 151 | https://github.com/wagoodman/dive#ui-configuration 152 | https://docs.docker.com/engine/release-notes/prior-releases/ 153 | https://docs.docker.com/engine/release-notes/prior-releases/#021-2013-05-01 154 | https://github.com/moby/moby/blob/v0.3.4/buildfile_test.go 155 | https://technology.doximity.com/articles/buildpacks-vs-dockerfiles 156 | https://www.baeldung.com/linux/docker-containers-evolution 157 | https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin 158 | https://kube.academy/courses/building-images 159 | https://containers.gitbook.io/build-containers-the-hard-way/#build-a-container-image-with-docker 160 | 161 | s2i: 162 | 163 | https://codeburst.io/source-to-image-s2i-by-example-9635c80b6108 164 | https://docs.openshift.com/online/pro/using_images/s2i_images/java.html 165 | https://dev.to/jromero/building-an-app-image-using-s2i-5gcp 166 | https://tomd.xyz/openshift-s2i-example/ 167 | 168 | 169 | 170 | Option 2: 171 | 172 | Without local maven you can only perform the tar build and direct import via load. 173 | 174 | [source] 175 | ---- 176 | docker run -it --rm --name my-maven-project -v "$(pwd)":/opt/app -w /opt/app maven:3.6.3-jdk-11 mvn compile com.google.cloud.tools:jib-maven-plugin:3.3.1:buildTar -Dimage=java-app:jib 177 | ---- -------------------------------------------------------------------------------- /stuff/walkthrough.adoc: -------------------------------------------------------------------------------- 1 | == Dockerfile 2 | 3 | === Classic 4 | 5 | Set to classic Docker mode: 6 | 7 | [source, bash] 8 | 9 | ---- 10 | export DOCKER_BUILDKIT=0 11 | ---- 12 | 13 | Build the code: 14 | 15 | ---- 16 | cd java 17 | mvn clean package 18 | ---- 19 | 20 | First dockerfile: 21 | 22 | ---- 23 | FROM ubuntu:20.10 24 | RUN apt update && apt install openjdk-11-jre-headless -y 25 | COPY target/simplecode-0.0.1-SNAPSHOT.jar /opt/app.jar 26 | CMD ["java","-jar","/opt/app.jar"] 27 | ---- 28 | 29 | Build image with custom Dockerfile: 30 | 31 | ---- 32 | docker build -f Dockerfile-simple-ubuntu -t maeddes/java-app:v-simple-ubuntu . 33 | ---- 34 | 35 | Show history of image: 36 | 37 | ---- 38 | docker history maeddes/java-app:v-simple-ubuntu 39 | ---- 40 | 41 | Build image with predefined base image: 42 | 43 | ---- 44 | docker build -f Dockerfile-simple-adoptopenjdk -t maeddes/java-app:v-simple-adoptopenjdk . 45 | ---- 46 | 47 | Build image with alternative base image: 48 | 49 | ---- 50 | docker history maeddes/java-app:v-simple-adoptopenjdk 51 | ---- 52 | 53 | Use tool "dive" to show detailed history of image: 54 | 55 | ---- 56 | dive maeddes/java-app:v-simple-ubuntu 57 | dive maeddes/java-app:v-simple-adoptopenjdk 58 | ---- 59 | 60 | Use ctrl+m || ctrl+u 61 | 62 | === Multi-Stage 63 | 64 | Build image with Multistage Dockerfile: 65 | 66 | ---- 67 | docker build -f Dockerfile-multistage-builder -t maeddes/java-app:v-multistage-builder . 68 | ---- 69 | 70 | Validate history: 71 | 72 | ---- 73 | docker history maeddes/java-app:v-multistage-builder 74 | ---- 75 | 76 | === BuildKit 77 | 78 | Change to new Docker mode: 79 | 80 | ---- 81 | export DOCKER_BUILDKIT=1 82 | ---- 83 | 84 | optional: remove maven and openjdk container image and show parallel download of images 85 | 86 | ---- 87 | docker build -f Dockerfile-multistage-builder -t maeddes/java-app:v-multistage-builder . 88 | ---- 89 | 90 | Alternative output 91 | 92 | ---- 93 | docker build --progress=plain -f Dockerfile-multistage-builder -t maeddes/java-app:v-multistage-builder . 94 | ---- 95 | 96 | change code - run again 97 | 98 | ---- 99 | docker build -f Dockerfile-multistage-experimental-cache -t maeddes/ava-app:v-multistage-experimental-cache . 100 | ---- 101 | 102 | change code - run again 103 | 104 | show unlayered state 105 | 106 | ---- 107 | docker history maeddes/ava-app:v-multistage-experimental-cache 108 | ---- 109 | 110 | change code - run again 111 | 112 | ---- 113 | docker build -f Dockerfile-multistage-layered -t maeddes/java-app:layered . 114 | ---- 115 | 116 | show layered state 117 | 118 | ---- 119 | docker history maeddes/java-app:layered 120 | ---- 121 | 122 | == Jib 123 | 124 | ---- 125 | mvn compile com.google.cloud.tools:jib-maven-plugin:3.0.0:build -Dimage=maeddes/java-app:jib 126 | ---- 127 | 128 | show no image locally with this tag 129 | 130 | https://hub.docker.com/ 131 | 132 | ---- 133 | mvn compile com.google.cloud.tools:jib-maven-plugin:3.0.0:dockerBuild -Dimage=maeddes/java-app:jib 134 | ---- 135 | ---- 136 | mvn clean package com.google.cloud.tools:jib-maven-plugin:3.0.0:dockerBuild -Dimage=maeddes/java-app:jib 137 | ---- 138 | 139 | ---- 140 | docker history maeddes/java-app:jib 141 | ---- 142 | 143 | == Cloud-native buildpacks 144 | 145 | ---- 146 | pack build maeddes/java-app:pack 147 | ---- 148 | 149 | ---- 150 | pack builder suggest 151 | ---- 152 | 153 | ---- 154 | pack set-default-builder paketobuildpacks/builder:tiny (deprecated) 155 | pack config default-builder paketobuildpacks/builder:tiny 156 | ---- 157 | 158 | == Paketo 159 | 160 | ---- 161 | mvn spring-boot:build-image -Dspring-boot.build-image.imageName=maeddes/java-app:paketo 162 | ---- 163 | 164 | == Native-Images 165 | 166 | ---- 167 | pack build maeddes/java-app:native --env BP_NATIVE_IMAGE=true 168 | gradle bootBuildImage 169 | ---- 170 | 171 | == Micronaut 172 | 173 | ---- 174 | pack build maeddes/micronaut-app:paketo 175 | ---- 176 | 177 | == s2i 178 | 179 | ---- 180 | s2i build --copy . fabric8/s2i-java:latest-java11 maeddes/java-app:s2i --incremental 181 | ---- 182 | 183 | -------------------------------------------------------------------------------- /tutorial/.gitignore: -------------------------------------------------------------------------------- 1 | public 2 | themes 3 | .vscode -------------------------------------------------------------------------------- /tutorial/.hugo_build.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maeddes/java-and-container/fcd3ccd8eacf220c71d24703bfc69b26c6de12e4/tutorial/.hugo_build.lock -------------------------------------------------------------------------------- /tutorial/README.md: -------------------------------------------------------------------------------- 1 | # Java and Container Tutorial -------------------------------------------------------------------------------- /tutorial/archetypes/default.md: -------------------------------------------------------------------------------- 1 | +++ 2 | title = '{{ replace .File.ContentBaseName "-" " " | title }}' 3 | date = {{ .Date }} 4 | draft = true 5 | +++ 6 | -------------------------------------------------------------------------------- /tutorial/config.toml: -------------------------------------------------------------------------------- 1 | baseURL = 'https://maeddes.github.io/java-and-container/' 2 | languageCode = 'en-us' 3 | title = 'Java and container exercises' 4 | -------------------------------------------------------------------------------- /tutorial/content/_index.md: -------------------------------------------------------------------------------- 1 | +++ 2 | archetype = "home" 3 | title = "Java and Container tutorial" 4 | +++ 5 | 6 | Hello Java and Container people! 7 | 8 | -------------------------------------------------------------------------------- /tutorial/content/buildpacks/_index.md: -------------------------------------------------------------------------------- 1 | +++ 2 | archetype = "home" 3 | title = "Cloud-native Buildpacks" 4 | +++ 5 | 6 | Hello Java and Container people! 7 | 8 | -------------------------------------------------------------------------------- /tutorial/content/dockerfiles/_index.md: -------------------------------------------------------------------------------- 1 | +++ 2 | archetype = "home" 3 | title = "Simple Dockerfiles" 4 | +++ 5 | 6 | Hello Java and Container people! 7 | 8 | -------------------------------------------------------------------------------- /tutorial/content/jib/_index.md: -------------------------------------------------------------------------------- 1 | +++ 2 | archetype = "home" 3 | title = "Jib" 4 | +++ 5 | 6 | Hello Java and Container people! 7 | 8 | -------------------------------------------------------------------------------- /tutorial/content/multistage/_index.md: -------------------------------------------------------------------------------- 1 | +++ 2 | archetype = "home" 3 | title = "Multistage Dockerfiles" 4 | +++ 5 | 6 | Hello Java and Container people! 7 | 8 | -------------------------------------------------------------------------------- /tutorial/content/tooling/_index.md: -------------------------------------------------------------------------------- 1 | +++ 2 | archetype = "home" 3 | title = "Tooling" 4 | +++ 5 | 6 | Hello Java and Container people! 7 | 8 | -------------------------------------------------------------------------------- /tutorial/hugo.toml: -------------------------------------------------------------------------------- 1 | theme = "hugo-theme-relearn-main" 2 | 3 | [params] 4 | linkTitle = 'Java & Container' 5 | author.name = 'maeddes' 6 | themeVariant = [ 7 | { identifier = 'relearn-dark' }, 8 | { identifier = 'zen-auto', name = 'Zen Light/Dark', auto = [ 'zen-light', 'zen-dark' ] }, 9 | { identifier = 'zen-dark' }, 10 | { identifier = 'retro-auto', name = 'Retro Learn/Neon', auto = [ 'learn', 'neon' ] }, 11 | { identifier = 'red' } 12 | ] 13 | 14 | 15 | # For search functionality 16 | [outputs] 17 | home = ["HTML", "RSS", "SEARCH", "SEARCHPAGE"] 18 | -------------------------------------------------------------------------------- /tutorial/layouts/partials/custom-footer.html: -------------------------------------------------------------------------------- 1 |
2 |

Footer

-------------------------------------------------------------------------------- /tutorial/layouts/partials/custom-header.html: -------------------------------------------------------------------------------- 1 |
2 |

Header

-------------------------------------------------------------------------------- /tutorial/layouts/partials/logo.html: -------------------------------------------------------------------------------- 1 |
2 |

Logo

-------------------------------------------------------------------------------- /tutorial/layouts/shortcodes/quizdown.html: -------------------------------------------------------------------------------- 1 |
2 | {{ .Inner }} 3 |
-------------------------------------------------------------------------------- /tutorial_tmp/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.21-alpine as base 2 | 3 | RUN apk add --update --no-cache --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community \ 4 | bash \ 5 | hugo 6 | 7 | FROM base as rt-dev 8 | 9 | WORKDIR /workspace 10 | 11 | COPY --chmod=0755 entrypoint.sh /tmp 12 | 13 | CMD [ "sh", "-c", "/tmp/entrypoint.sh" ] 14 | 15 | 16 | FROM base as builder 17 | 18 | WORKDIR /opt/app 19 | 20 | COPY . . 21 | 22 | RUN wget -qO- https://github.com/McShelby/hugo-theme-relearn/archive/main.zip | unzip -d themes - 23 | 24 | RUN hugo 25 | 26 | 27 | FROM nginx:1.25-alpine as rt 28 | 29 | ARG USER=otel 30 | 31 | WORKDIR /usr/share/nginx/html 32 | 33 | COPY --from=builder /opt/app/public . 34 | 35 | EXPOSE 80/tcp -------------------------------------------------------------------------------- /tutorial_tmp/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | wget -qO- https://github.com/McShelby/hugo-theme-relearn/archive/main.zip | unzip -d themes - 4 | hugo server --bind=0.0.0.0 --port=80 --poll=700 -------------------------------------------------------------------------------- /tutorial_tmp/static/css/chroma-github.css: -------------------------------------------------------------------------------- 1 | /* Background */ .bg { background-color: #ffffff; } 2 | /* PreWrapper */ .chroma { background-color: #ffffff; } 3 | /* Other */ .chroma .x { } 4 | /* Error */ .chroma .err { color: #a61717; background-color: #e3d2d2 } 5 | /* CodeLine */ .chroma .cl { } 6 | /* LineLink */ .chroma .lnlinks { outline: none; text-decoration: none; color: inherit } 7 | /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } 8 | /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; } 9 | /* LineHighlight */ .chroma .hl { background-color: #e5e5e5 } 10 | /* LineNumbersTable */ .chroma .lnt { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } 11 | /* LineNumbers */ .chroma .ln { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } 12 | /* Line */ .chroma .line { display: flex; } 13 | /* Keyword */ .chroma .k { color: #000000; font-weight: bold } 14 | /* KeywordConstant */ .chroma .kc { color: #000000; font-weight: bold } 15 | /* KeywordDeclaration */ .chroma .kd { color: #000000; font-weight: bold } 16 | /* KeywordNamespace */ .chroma .kn { color: #000000; font-weight: bold } 17 | /* KeywordPseudo */ .chroma .kp { color: #000000; font-weight: bold } 18 | /* KeywordReserved */ .chroma .kr { color: #000000; font-weight: bold } 19 | /* KeywordType */ .chroma .kt { color: #445588; font-weight: bold } 20 | /* Name */ .chroma .n { } 21 | /* NameAttribute */ .chroma .na { color: #008080 } 22 | /* NameBuiltin */ .chroma .nb { color: #0086b3 } 23 | /* NameBuiltinPseudo */ .chroma .bp { color: #999999 } 24 | /* NameClass */ .chroma .nc { color: #445588; font-weight: bold } 25 | /* NameConstant */ .chroma .no { color: #008080 } 26 | /* NameDecorator */ .chroma .nd { color: #3c5d5d; font-weight: bold } 27 | /* NameEntity */ .chroma .ni { color: #800080 } 28 | /* NameException */ .chroma .ne { color: #990000; font-weight: bold } 29 | /* NameFunction */ .chroma .nf { color: #990000; font-weight: bold } 30 | /* NameFunctionMagic */ .chroma .fm { } 31 | /* NameLabel */ .chroma .nl { color: #990000; font-weight: bold } 32 | /* NameNamespace */ .chroma .nn { color: #555555 } 33 | /* NameOther */ .chroma .nx { } 34 | /* NameProperty */ .chroma .py { } 35 | /* NameTag */ .chroma .nt { color: #000080 } 36 | /* NameVariable */ .chroma .nv { color: #008080 } 37 | /* NameVariableClass */ .chroma .vc { color: #008080 } 38 | /* NameVariableGlobal */ .chroma .vg { color: #008080 } 39 | /* NameVariableInstance */ .chroma .vi { color: #008080 } 40 | /* NameVariableMagic */ .chroma .vm { } 41 | /* Literal */ .chroma .l { } 42 | /* LiteralDate */ .chroma .ld { } 43 | /* LiteralString */ .chroma .s { color: #dd1144 } 44 | /* LiteralStringAffix */ .chroma .sa { color: #dd1144 } 45 | /* LiteralStringBacktick */ .chroma .sb { color: #dd1144 } 46 | /* LiteralStringChar */ .chroma .sc { color: #dd1144 } 47 | /* LiteralStringDelimiter */ .chroma .dl { color: #dd1144 } 48 | /* LiteralStringDoc */ .chroma .sd { color: #dd1144 } 49 | /* LiteralStringDouble */ .chroma .s2 { color: #dd1144 } 50 | /* LiteralStringEscape */ .chroma .se { color: #dd1144 } 51 | /* LiteralStringHeredoc */ .chroma .sh { color: #dd1144 } 52 | /* LiteralStringInterpol */ .chroma .si { color: #dd1144 } 53 | /* LiteralStringOther */ .chroma .sx { color: #dd1144 } 54 | /* LiteralStringRegex */ .chroma .sr { color: #009926 } 55 | /* LiteralStringSingle */ .chroma .s1 { color: #dd1144 } 56 | /* LiteralStringSymbol */ .chroma .ss { color: #990073 } 57 | /* LiteralNumber */ .chroma .m { color: #009999 } 58 | /* LiteralNumberBin */ .chroma .mb { color: #009999 } 59 | /* LiteralNumberFloat */ .chroma .mf { color: #009999 } 60 | /* LiteralNumberHex */ .chroma .mh { color: #009999 } 61 | /* LiteralNumberInteger */ .chroma .mi { color: #009999 } 62 | /* LiteralNumberIntegerLong */ .chroma .il { color: #009999 } 63 | /* LiteralNumberOct */ .chroma .mo { color: #009999 } 64 | /* Operator */ .chroma .o { color: #000000; font-weight: bold } 65 | /* OperatorWord */ .chroma .ow { color: #000000; font-weight: bold } 66 | /* Punctuation */ .chroma .p { } 67 | /* Comment */ .chroma .c { color: #999988; font-style: italic } 68 | /* CommentHashbang */ .chroma .ch { color: #999988; font-style: italic } 69 | /* CommentMultiline */ .chroma .cm { color: #999988; font-style: italic } 70 | /* CommentSingle */ .chroma .c1 { color: #999988; font-style: italic } 71 | /* CommentSpecial */ .chroma .cs { color: #999999; font-weight: bold; font-style: italic } 72 | /* CommentPreproc */ .chroma .cp { color: #999999; font-weight: bold; font-style: italic } 73 | /* CommentPreprocFile */ .chroma .cpf { color: #999999; font-weight: bold; font-style: italic } 74 | /* Generic */ .chroma .g { } 75 | /* GenericDeleted */ .chroma .gd { color: #000000; background-color: #ffdddd } 76 | /* GenericEmph */ .chroma .ge { color: #000000; font-style: italic } 77 | /* GenericError */ .chroma .gr { color: #aa0000 } 78 | /* GenericHeading */ .chroma .gh { color: #999999 } 79 | /* GenericInserted */ .chroma .gi { color: #000000; background-color: #ddffdd } 80 | /* GenericOutput */ .chroma .go { color: #888888 } 81 | /* GenericPrompt */ .chroma .gp { color: #555555 } 82 | /* GenericStrong */ .chroma .gs { font-weight: bold } 83 | /* GenericSubheading */ .chroma .gu { color: #aaaaaa } 84 | /* GenericTraceback */ .chroma .gt { color: #aa0000 } 85 | /* GenericUnderline */ .chroma .gl { text-decoration: underline } 86 | /* TextWhitespace */ .chroma .w { color: #bbbbbb } 87 | -------------------------------------------------------------------------------- /tutorial_tmp/static/css/theme-relearn-light.css: -------------------------------------------------------------------------------- 1 | /* my-custom-variant */ 2 | :root { 3 | --PRIMARY-color: rgba( 125, 201, 3, 1 ); /* brand primary color */ 4 | --SECONDARY-color: rgba( 72, 106, 201, 1 ); /* brand secondary color */ 5 | --ACCENT-color: rgba( 255, 136, 255, 1 ); /* brand accent color, used for search highlights */ 6 | --MAIN-LINK-HOVER-color: rgba( 32, 40, 145, 1 ); /* hoverd link color of content */ 7 | --MAIN-BG-color: rgba( 255, 255, 255, 1 ); /* background color of content */ 8 | --MAIN-TEXT-color: rgba( 0, 0, 0, 1 ); /* text color of content and h1 titles */ 9 | --MAIN-TITLES-TEXT-color: rgba( 16, 16, 16, 1 ); /* text color of h2-h6 titles and transparent box titles */ 10 | --CODE-theme: github; /* name of the chroma stylesheet file */ 11 | --CODE-BLOCK-color: rgba( 39, 40, 34, 1 ); /* fallback text color of block code; should be adjusted to your selected chroma style */ 12 | --CODE-BLOCK-BG-color: rgba( 250, 250, 250, 1 ); /* fallback background color of block code; should be adjusted to your selected chroma style */ 13 | --CODE-BLOCK-BORDER-color: rgba( 216, 216, 216, 1 ); /* border color of block code */ 14 | --CODE-INLINE-color: rgba( 94, 94, 94, 1 ); /* text color of inline code */ 15 | --CODE-INLINE-BG-color: rgba( 255, 250, 233, 1 ); /* background color of inline code */ 16 | --CODE-INLINE-BORDER-color: rgba( 248, 232, 200, 1 ); /* border color of inline code */ 17 | --BROWSER-theme: light; /* name of the theme for browser scrollbars of the main section */ 18 | --MERMAID-theme: default; /* name of the default Mermaid theme for this variant, can be overridden in hugo.toml */ 19 | --OPENAPI-theme: light; /* name of the default OpenAPI theme for this variant, can be overridden in hugo.toml */ 20 | --OPENAPI-CODE-theme: idea; /* name of the default OpenAPI code theme for this variant, can be overridden in hugo.toml */ 21 | --MENU-HEADER-BG-color: rgba( 88, 99, 172, 1 ); /* background color of menu header */ 22 | --MENU-HOME-LINK-color: rgba( 64, 64, 64, 1 ); /* home button color if configured */ 23 | --MENU-HOME-LINK-HOVER-color: rgba( 0, 0, 0, 1 ); /* hoverd home button color if configured */ 24 | --MENU-SEARCH-color: rgba( 224, 224, 224, 1 ); /* text and icon color of search box */ 25 | --MENU-SEARCH-BG-color: rgba( 50, 50, 50, 1 ); /* background color of search box */ 26 | --MENU-SEARCH-BORDER-color: rgba( 224, 224, 224, 1 ); /* border color of search box */ 27 | --MENU-SECTIONS-BG-color: rgba( 40, 40, 40, 1 ); /* background of the menu; this is NOT just a color value but can be a complete CSS background definition including gradients, etc. */ 28 | --MENU-SECTIONS-ACTIVE-BG-color: rgba( 0, 0, 0, .166 ); /* background color of the active menu section */ 29 | --MENU-SECTIONS-LINK-color: rgba( 186, 186, 186, 1 ); /* link color of menu topics */ 30 | --MENU-SECTIONS-LINK-HOVER-color: rgba( 255, 255, 255, 1 ); /* hoverd link color of menu topics */ 31 | --MENU-SECTION-ACTIVE-CATEGORY-color: rgba( 68, 68, 68, 1 ); /* text color of the displayed menu topic */ 32 | --MENU-SECTION-SEPARATOR-color: rgba( 96, 96, 96, 1 ); /* separator color between menu sections and menu footer */ 33 | --BOX-CAPTION-color: rgba( 255, 255, 255, 1 ); /* text color of colored box titles */ 34 | --BOX-BG-color: rgba( 255, 255, 255, .833 ); /* background color of colored boxes */ 35 | --BOX-TEXT-color: rgba( 16, 16, 16, 1 ); /* text color of colored box content */ 36 | } 37 | --------------------------------------------------------------------------------