Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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/*
Expand All @@ -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"]
5 changes: 2 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
16 changes: 4 additions & 12 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
49 changes: 49 additions & 0 deletions docker/startup.sh
Original file line number Diff line number Diff line change
@@ -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
18 changes: 0 additions & 18 deletions gradle/github/docker.gradle

This file was deleted.

17 changes: 2 additions & 15 deletions gradle/github/jar.gradle
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
17 changes: 17 additions & 0 deletions gradle/tasks/apitest.gradle → gradle/tasks/api-test.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
}
Loading