diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 17663f7..3500152 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,6 +85,55 @@ jobs: fail_ci_if_error: false token: ${{ secrets.CODECOV_TOKEN }} + docker: + name: Docker image + runs-on: ubuntu-latest + needs: build-test + + permissions: + contents: read + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Assert two named stages and distroless runtime base + run: | + grep -q 'AS builder' Dockerfile + grep -q 'gcr.io/distroless/java21-debian12:nonroot AS runtime' Dockerfile + + - name: Build image + run: docker build -t fincore-ledger:ci . + + - name: Assert nonroot runtime user + run: | + user=$(docker inspect -f '{{.Config.User}}' fincore-ledger:ci) + echo "runtime user: $user" + [ "$user" = "nonroot" ] || [ "$user" = "65532" ] + + - name: Assert image size under 300 MB + run: | + size=$(docker image inspect -f '{{.Size}}' fincore-ledger:ci) + echo "image size: $((size / 1024 / 1024)) MB" + [ "$size" -lt 314572800 ] + + - name: Smoke run (jvm launches the jar and spring boot starts) + run: | + timeout 90 docker run --rm fincore-ledger:ci --spring.profiles.active=test > out.log 2>&1 || true + grep -q 'Starting LedgerApplication' out.log || { cat out.log; exit 1; } + + - name: Trivy image scan (no CRITICAL) + uses: aquasecurity/trivy-action@master + with: + scan-type: image + image-ref: fincore-ledger:ci + severity: CRITICAL + exit-code: "1" + ignore-unfixed: true + env: + TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db + TRIVY_JAVA_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-java-db + lint-security: name: Security Scan runs-on: ubuntu-latest diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..52f3989 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM eclipse-temurin:21-jdk AS builder +WORKDIR /workspace +COPY . . +RUN chmod +x gradlew \ + && ./gradlew :services:ledger:bootJar --no-daemon -x test \ + && find services/ledger/build/libs -name '*.jar' ! -name '*-plain.jar' -exec cp {} /workspace/app.jar \; + +FROM gcr.io/distroless/java21-debian12:nonroot AS runtime +WORKDIR /app +COPY --from=builder /workspace/app.jar /app/app.jar +EXPOSE 8080 +ENTRYPOINT ["java", "-jar", "/app/app.jar"] diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6556027..3222982 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] kotlin = "2.0.21" -spring-boot = "3.5.2" +spring-boot = "3.5.15" hibernate = "6.6.18.Final" liquibase = "4.31.1" postgres-jdbc = "42.7.4"