Lab 1 Report
Successful run-game job: https://gitlab.stud.atlantis.ugent.be/thibo.devogelaere/devops-project/-/jobs/248608
Final Lab 1 YML structure
Found at: .gitlab-ci.yml
image: gitlab.stud.atlantis.ugent.be:5050/utils/docker/eclipse-temurin:25-jdk
variables:
MAVEN_CLI_OPTS: "--batch-mode"
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository"
stages:
- build
- package
- execute
cache:
key: maven-cache-${CI_COMMIT_REF_SLUG}
paths:
- .m2/repository/
maven-build:
stage: build
script:
- ./mvnw $MAVEN_CLI_OPTS $MAVEN_OPTS compile
maven-container-image-generation:
stage: package
variables:
QUARKUS_CONTAINER_IMAGE_PUSH: true
QUARKUS_CONTAINER_IMAGE_USERNAME: $CI_REGISTRY_USER
QUARKUS_CONTAINER_IMAGE_PASSWORD: $CI_REGISTRY_PASSWORD
QUARKUS_CONTAINER_IMAGE_REGISTRY: $CI_REGISTRY
QUARKUS_CONTAINER_IMAGE_GROUP: $CI_PROJECT_PATH
QUARKUS_CONTAINER_IMAGE_TAG: "latest"
artifacts:
paths:
- target/*.jar
expire_in: 1 hour
script:
# == DEBUG COMMANDS LAB 1 ==
# (uncomment below to enable)
# - printenv
# - echo $QUARKUS_CONTAINER_IMAGE_REGISTRY/$QUARKUS_CONTAINER_IMAGE_GROUP/logic-service:$QUARKUS_CONTAINER_IMAGE_TAG
- ./mvnw $MAVEN_CLI_OPTS $MAVEN_OPTS package
run-game:
stage: execute
variables:
PLAYER_NAME: CI/CD Player
LOGIC_URL: http://logic-service:8080
TURN_INTERVAL_MS: 25
TURN_LIMIT: 100
QUARKUS_HTTP_HOST: "0.0.0.0"
services:
- name: $CI_REGISTRY_IMAGE/logic-service:latest
alias: logic-service
image:
name: gitlab.stud.atlantis.ugent.be:5050/utils/docker/devops-runner:latest
entrypoint:
- ""
script:
- java -cp /app/resources:/app/classes:/app/libs/* be.ugent.devops.gamehost.services.runner.LauncherKt
Problems
- At first, the game couldn't connect to the logic service in the
run-gamestep. I solved this by adding an alias namedlogic-serviceto the service definition. - It was hard to get the caching working. Initially, it always showed a warning that the
.m2/repositorydirectory couldn't be found, so I added amkdircommand to themaven-buildstep. This fixed the warning and even made it report a single found cached file in the directory. However, it still downloaded all the Maven dependencies in both the first and second stages. Eventually, I figured out that I needed to supply$MAVEN_OPTSto the commands of both stages. At last, I saw the cache do its job and the pipeline times went down significantly (from 1m41s to 55s).
Questions
What is ./mvnw and what is the advantage of using it above mvn?
Quoting the lab documentation:
The former refers to a Maven wrapper script that comes with the project. This wrapper downloads a project-compatible version of Maven that will only be used within the context of this project. Using Maven wrapper makes it easier for developers to collaborate and prevents you from having to install Maven on your system.
Explain the key differences between GitLab's cache and artifacts mechanisms. For each of Maven dependencies and build files, explain which mechanism you chose and why. What are the trade-offs of your choices?
| Feature | Cache | Artifacts |
|---|---|---|
| Purpose | To speed up jobs by reusing files across different jobs and pipelines. | To share files from one job to another within the same pipeline. |
| Retention | Can persist across multiple pipeline executions, configurable with a key. | Has a defined expiration time and is usually removed after the pipeline finishes. |
| Scope | Available to any job within the same pipeline or future pipelines. | Limited to the job that creates them and subsequent jobs in the same pipeline. |
| Usage Pattern | Typically used for dependencies, libraries, or tooling files. | Typically used for build outputs like binaries, packaged applications, or reports. |
| Configuration | Configured at the job or global level for cache paths. | Configured at the job level in artifacts settings. |
In the CI/CD configuration, caching is used for Maven dependencies stored in the directory .m2/repository. This speeds up the build process by preventing the need to re-download dependencies for each pipeline run, which greatly improves efficiency.
The artifact saved is the JAR file generated in the maven-container-image-generation job, located in the target directory. This artifact is important as it allows subsequent jobs, like the run-game stage, to access and execute the built application without needing to rebuild it.
In this lab, we use a 25-jre image as the base for our runtime container and a 25-jdk image for the CI/CD build jobs. Explain the reasoning behind this choice. What would be the impact (positive or negative) of using 25-jdk for both? What about using 25-jre for both?
Quoting the lab documentation:
When building container images for Java applications, it's important to understand the difference between JDK (Java Development Kit) and JRE (Java Runtime Environment) images:
In this configuration, we use the 25-jre image as the base for our runtime container because our application is already compiled. This follows the best practice of keeping production images as small and secure as possible. The build process itself (happening in the CI/CD pipeline) will use the 25-jdk image which includes the necessary tools to compile the code.
- JDK images (e.g., eclipse-temurin:25-jdk) contain the full Java Development Kit, including the compiler (javac), debugging tools, and the runtime environment. These images are larger but necessary for building Java applications.
- JRE images (e.g., eclipse-temurin:25-jre) contain only the Java Runtime Environment needed to run compiled Java applications. These images are significantly smaller and more secure as they exclude unnecessary development tools.
Using JDK for both would work, but it would make the pipeline slightly more bloated and slower. JRE for the base image is sufficient for now and thus preferred.
Using JRE for both would break the build pipeline: since we are building a Java application, we need the build tools provided by JDK.