diff --git a/Dockerfile b/Dockerfile index dfa2fe4..82c6617 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,8 @@ # Dockerfile (project root) -FROM eclipse-temurin:25-jre +ARG BASE_IMAGE +FROM ${BASE_IMAGE:-eclipse-temurin:25-jre} -# minimal runtime tooling for healthcheck +# install curl for debugging RUN apt-get update \ && apt-get install -y --no-install-recommends curl \ && rm -rf /var/lib/apt/lists/* @@ -10,15 +11,15 @@ RUN apt-get update \ RUN groupadd -r app && useradd -r -g app app WORKDIR /app -# copy all jars (bootJar + plain). We'll run the non-plain jar. +# copy startup script and app jar file +COPY docker/* /app/ COPY build/libs/*.jar /app/ +COPY lib/applicationinsights.json /app/ -EXPOSE ${SERVER_PORT:-8082} -ENV JAVA_OPTS="-XX:MaxRAMPercentage=75 -XX:+AlwaysActAsServerClassMachine" - -HEALTHCHECK --interval=10s --timeout=3s --start-period=20s --retries=15 \ - CMD curl -fsS http://localhost:${SERVER_PORT:-8082}/actuator/health | grep -q '"status":"UP"' || exit 1 +# Not sure this does anything useful we can drop once we sort certificates +RUN test -n "$JAVA_HOME" \ + && test -f "$JAVA_HOME/lib/security/cacerts" \ + && chmod 777 "$JAVA_HOME/lib/security/cacerts" USER app -# pick the Boot fat jar (exclude '-plain.jar') -ENTRYPOINT ["sh","-c","exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar $(ls /app/*.jar | grep -v 'plain' | head -n1)"] +ENTRYPOINT ["/bin/sh","./startup.sh"] \ No newline at end of file diff --git a/build.gradle b/build.gradle index afa860a..30dc855 100644 --- a/build.gradle +++ b/build.gradle @@ -19,15 +19,14 @@ apply { from("$rootDir/gradle/dependencies/spring-core.gradle") from("$rootDir/gradle/dependencies/spring-db.gradle") - from("$rootDir/gradle/tasks/apitest.gradle") - from("$rootDir/gradle/github/repositories.gradle") from("$rootDir/gradle/github/java.gradle") from("$rootDir/gradle/github/dependency.gradle") from("$rootDir/gradle/github/pmd.gradle") from("$rootDir/gradle/github/test.gradle") from("$rootDir/gradle/github/jar.gradle") - from("$rootDir/gradle/github/docker.gradle") + + from("$rootDir/gradle/tasks/api-test.gradle") } springBoot { diff --git a/docker-compose.yml b/docker-compose.yml index 3f4175d..1d017ba 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,29 +1,21 @@ services: db: - container_name: db - image: postgres:16-alpine + image: postgres:18-alpine environment: - POSTGRES_DB: postgres + POSTGRES_DB: template-db # use specific name to reduce flyway conflicts POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres ports: - "5432:5432" - healthcheck: - test: [ "CMD-SHELL", "pg_isready -U postgres" ] - interval: 10s - timeout: 5s - retries: 5 app: - container_name: app build: context: . dockerfile: Dockerfile depends_on: - db: - condition: service_healthy + - db environment: - APP_NAME_DATASOURCE_URL: jdbc:postgresql://db:5432/postgres + APP_NAME_DATASOURCE_URL: jdbc:postgresql://db:5432/template-db APP_NAME_DATASOURCE_USERNAME: postgres APP_NAME_DATASOURCE_PASSWORD: postgres ports: diff --git a/docker/startup.sh b/docker/startup.sh new file mode 100644 index 0000000..ffd426f --- /dev/null +++ b/docker/startup.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env sh +# Script to perform any custom docker startup actions +# Allows local running where the jarfile is under ./build/lib +# or dockerfile running where the app jarfile is under /app +# +logmsg() { + SCRIPTNAME=$(basename $0) + echo "$SCRIPTNAME : $1" +} + +logmsg "running and loading certificates ..." +if [ -z "$JAVA_HOME" ]; then + export JAVA_HOME="/usr/local/openjdk-21" +fi +export KEYSTORE="$JAVA_HOME/lib/security/cacerts" +if [ -z "$CERTS_DIR" ]; then + logmsg "Warning - expects \$CERTS_DIR to be set. i.e. export CERTS_DIR="/etc/certs + logmsg "Defaulting to /etc/certs" + export CERTS_DIR="/etc/certs" +fi + +if [ ! -f "$KEYSTORE" ]; then + logmsg "Error - expects keystore $KEYSTORE to already exist" + exit 1 +fi + +export count=1 +logmsg "Loading certificates from $CERTS_DIR into keystore $KEYSTORE" +for FILE in $(ls $CERTS_DIR) +do + alias="mojcert$count" + logmsg "Adding $CERTS_DIR/$FILE to keystore with alias $alias" + keytool -importcert -file $CERTS_DIR/$FILE -keystore $KEYSTORE -storepass changeit -alias $alias -noprompt + count=$((count+1)) +done + +keytool -list -keystore $KEYSTORE -storepass changeit | grep "Your keystore contains" + +export LOCALJARFILE=$(ls ./build/libs/*.jar 2>/dev/null | grep -v 'plain' | head -n1) +export DOCKERJARFILE=$(ls /app/*.jar 2>/dev/null | grep -v 'plain' | head -n1) +if [ -f "$DOCKERJARFILE" ]; then + logmsg "Running docker java jarfile $DOCKERJARFILE" + java -jar $DOCKERJARFILE +elif [ -f "$LOCALJARFILE" ]; then + logmsg "Running local java jarfile $LOCALJARFILE" + java -jar $LOCALJARFILE +else + logmsg "ERROR - No jarfile found. Unable to start application" +fi diff --git a/gradle/github/docker.gradle b/gradle/github/docker.gradle deleted file mode 100644 index 4d31f93..0000000 --- a/gradle/github/docker.gradle +++ /dev/null @@ -1,18 +0,0 @@ -dockerCompose { - useComposeFiles = ['docker-compose.yml'] - startedServices = ['app', 'db'] - - buildBeforeUp = true - waitForTcpPorts = true - upAdditionalArgs = ['--wait', '--wait-timeout', '120'] - - captureContainersOutput = true - removeOrphans = true - stopContainers = true - removeContainers = true - - projectName = "${rootProject.name}-it".replaceAll('[^A-Za-z0-9]', '') - - useDockerComposeV2 = true - dockerExecutable = 'docker' -} \ No newline at end of file diff --git a/gradle/github/jar.gradle b/gradle/github/jar.gradle index ab1810d..1f40dbf 100644 --- a/gradle/github/jar.gradle +++ b/gradle/github/jar.gradle @@ -1,19 +1,6 @@ jar { - enabled = true - archiveClassifier.set('plain') - manifest { - attributes( - 'Implementation-Title': project.name, - 'Implementation-Version': project.version.toString() - ) - } - if (file("CHANGELOG.md").exists()) { - from('CHANGELOG.md') { - into 'META-INF' - } - } else { - println "⚠️ CHANGELOG.md not found, skipping inclusion in JAR" - } + // we dont need jar task which just creates *-plain.jar + enabled = false } bootJar { diff --git a/gradle/tasks/apitest.gradle b/gradle/tasks/api-test.gradle similarity index 82% rename from gradle/tasks/apitest.gradle rename to gradle/tasks/api-test.gradle index e52a7c7..1ad26d4 100644 --- a/gradle/tasks/apitest.gradle +++ b/gradle/tasks/api-test.gradle @@ -61,3 +61,20 @@ dependencies { apiTestCompileOnly group: 'org.projectlombok', name: 'lombok', version: lombokVersion apiTestAnnotationProcessor group: 'org.projectlombok', name: 'lombok', version: lombokVersion } + +dockerCompose { + useComposeFiles = ['docker-compose.yml'] + startedServices = ['app', 'db'] + + buildBeforeUp = true + waitForTcpPorts = true + upAdditionalArgs = ['--wait', '--wait-timeout', '120'] + + captureContainersOutput = true + removeOrphans = true + stopContainers = true + removeContainers = true + + useDockerComposeV2 = true + dockerExecutable = 'docker' +}