add kontor-javalin and change to multistage Dockerfile for Gradle projects #81
@@ -113,6 +113,28 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
kontor-javalin:
|
||||||
|
build:
|
||||||
|
context: ./kontor-javalin
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
tags:
|
||||||
|
- kontor-javalin:0.2.0-SNAPSHOT
|
||||||
|
image: kontor-javalin:0.2.0-SNAPSHOT
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://kontor-javalin:8400/health"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
networks:
|
||||||
|
- database
|
||||||
|
- integration
|
||||||
|
- frontend
|
||||||
|
ports:
|
||||||
|
- 8400:8400
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
integration:
|
integration:
|
||||||
|
|||||||
@@ -1,5 +1,25 @@
|
|||||||
FROM alpine/java:21-jdk
|
# ----------------------------------------------------------------------- #
|
||||||
|
FROM gradle:9.2.1-jdk21 AS builder
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
ADD build/libs/kontor-spring-0.2.0-SNAPSHOT.jar app.jar
|
COPY ./src/main/ ./src/main/
|
||||||
EXPOSE 8000
|
COPY ./build.gradle ./
|
||||||
CMD ["java", "-jar", "-Dspring.profiles.active=prod", "-Dvaadin.productionMode=true", "app.jar"]
|
COPY ./gradle.properties ./
|
||||||
|
COPY ./settings.gradle ./
|
||||||
|
COPY ./gradle/libs.versions.toml ./gradle/
|
||||||
|
RUN gradle build --no-daemon
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------- #
|
||||||
|
FROM alpine/java:21-jre AS run
|
||||||
|
|
||||||
|
RUN apk --no-cache add curl
|
||||||
|
|
||||||
|
RUN adduser --system appuser
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
COPY --from=builder --chown=appuser:appuser /build/libs/kontor-javalin-0.2.0-SNAPSHOT.jar app.jar
|
||||||
|
|
||||||
|
EXPOSE 8400
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
CMD ["java", "-jar", "app.jar"]
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id 'application'
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation project(":models") // We need this dependency for serializing persons to JSON
|
|
||||||
implementation project(":services") // We'll make use of the InMemoryPersonReader soon
|
|
||||||
|
|
||||||
implementation libs.javalin // Pulling in Javalin
|
|
||||||
implementation libs.jackson // For JSON serialization of persons
|
|
||||||
implementation libs.slf4j // To see some Javalin logging
|
|
||||||
}
|
|
||||||
|
|
||||||
application {
|
|
||||||
mainClass = "de.thpeetz.kontor.api.Main"
|
|
||||||
mainModule = "de.thpeetz.kontor.api"
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
module de.thpeetz.kontor.api {
|
|
||||||
requires io.javalin;
|
|
||||||
requires com.fasterxml.jackson.databind;
|
|
||||||
requires org.slf4j;
|
|
||||||
requires kotlin.stdlib;
|
|
||||||
|
|
||||||
requires de.thpeetz.kontor.services;
|
|
||||||
|
|
||||||
uses de.thpeetz.kontor.services.api.PersonReader;
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,28 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'org.javamodularity.moduleplugin' version '2.0.0' apply false
|
id 'java'
|
||||||
}
|
}
|
||||||
|
|
||||||
subprojects {
|
repositories {
|
||||||
repositories {
|
mavenCentral()
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
apply plugin: "org.javamodularity.moduleplugin"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation libs.javalin // Pulling in Javalin
|
||||||
|
implementation libs.jackson // For JSON serialization of persons
|
||||||
|
implementation libs.slf4j // To see some Javalin logging
|
||||||
|
}
|
||||||
|
|
||||||
|
task fatJar(type: Jar) {
|
||||||
|
manifest {
|
||||||
|
attributes 'Main-Class': 'de.thpeetz.kontor.api.Main'
|
||||||
|
}
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||||
|
with jar
|
||||||
|
}
|
||||||
|
|
||||||
|
build.dependsOn fatJar
|
||||||
|
|
||||||
wrapper {
|
wrapper {
|
||||||
gradleVersion = "9.2.1"
|
gradleVersion = "9.2.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id 'java-library'
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
module de.thpeetz.kontor.models {
|
|
||||||
// We're exporting the only package we have in this subproject
|
|
||||||
exports de.thpeetz.kontor.models;
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id 'java-library'
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation project(":models") // <-- add dependency to models subproject
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import de.thpeetz.kontor.services.api.PersonReader;
|
|
||||||
import de.thpeetz.kontor.services.inmemory.InMemoryPersonReader;
|
|
||||||
|
|
||||||
module de.thpeetz.kontor.services {
|
|
||||||
exports de.thpeetz.kontor.services.api;
|
|
||||||
|
|
||||||
requires de.thpeetz.kontor.models;
|
|
||||||
|
|
||||||
// We're telling the ServiceLoader that the InMemoryPersonReader provides the implementation for the PersonReader interface
|
|
||||||
provides PersonReader with InMemoryPersonReader;
|
|
||||||
}
|
|
||||||
@@ -1,6 +1 @@
|
|||||||
rootProject.name = 'kontor-javalin'
|
rootProject.name = 'kontor-javalin'
|
||||||
|
|
||||||
include ':models'
|
|
||||||
include ':services'
|
|
||||||
include ':api'
|
|
||||||
|
|
||||||
|
|||||||
+16
-9
@@ -1,21 +1,20 @@
|
|||||||
package de.thpeetz.kontor.api;
|
package de.thpeetz.kontor.api;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import de.thpeetz.kontor.services.inmemory.InMemoryPersonReader;
|
||||||
import io.javalin.Javalin;
|
import io.javalin.Javalin;
|
||||||
import de.thpeetz.kontor.services.api.PersonReader;
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import java.util.ServiceLoader;
|
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
private static Logger logger = LoggerFactory.getLogger(Main.class);
|
private static Logger logger = LoggerFactory.getLogger(Main.class);
|
||||||
private static short port = 7312;
|
private static short port = 8400;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
var personReader = ServiceLoader.load(PersonReader.class).findFirst().get(); // <-- Getting an implementation
|
var personReader = new InMemoryPersonReader();
|
||||||
// for the PersonReader interface
|
|
||||||
// from the ServiceLoader
|
|
||||||
var objMapper = new ObjectMapper();
|
var objMapper = new ObjectMapper();
|
||||||
var result = objMapper.valueToTree(personReader.getAll());
|
var result = objMapper.valueToTree(personReader.getAll());
|
||||||
|
|
||||||
@@ -23,7 +22,15 @@ public class Main {
|
|||||||
|
|
||||||
var app = Javalin.create().start(port);
|
var app = Javalin.create().start(port);
|
||||||
app.get("/ping", ctx -> ctx.result("pong"));
|
app.get("/ping", ctx -> ctx.result("pong"));
|
||||||
app.get("/persons", ctx -> ctx.json(result));
|
app.get("/health", ctx -> {
|
||||||
|
HashMap<String, String> status = new HashMap<>();
|
||||||
|
status.put("status", "ok");
|
||||||
|
ctx.json(status);
|
||||||
|
});
|
||||||
|
app.get("/persons", ctx -> {
|
||||||
|
logger.info("persons called");
|
||||||
|
ctx.json(result);
|
||||||
|
});
|
||||||
|
|
||||||
logger.info("API's alive for real :-)))");
|
logger.info("API's alive for real :-)))");
|
||||||
}
|
}
|
||||||
-1
@@ -1,7 +1,6 @@
|
|||||||
package de.thpeetz.kontor.services.api;
|
package de.thpeetz.kontor.services.api;
|
||||||
|
|
||||||
import de.thpeetz.kontor.models.Person;
|
import de.thpeetz.kontor.models.Person;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface PersonReader {
|
public interface PersonReader {
|
||||||
+1
@@ -6,6 +6,7 @@ import java.util.List;
|
|||||||
import de.thpeetz.kontor.services.api.PersonReader;
|
import de.thpeetz.kontor.services.api.PersonReader;
|
||||||
|
|
||||||
public class InMemoryPersonReader implements PersonReader {
|
public class InMemoryPersonReader implements PersonReader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Person> getAll() {
|
public List<Person> getAll() {
|
||||||
return List.of(
|
return List.of(
|
||||||
@@ -1,5 +1,25 @@
|
|||||||
FROM alpine/java:21-jdk
|
# ----------------------------------------------------------------------- #
|
||||||
|
FROM gradle:8.7-jdk AS builder
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
ADD build/libs/kontor-spring-0.2.0-SNAPSHOT.jar app.jar
|
COPY ./src/main/ ./src/main/
|
||||||
EXPOSE 8000
|
COPY ./frontend/ ./frontend/
|
||||||
|
COPY ./build.gradle ./
|
||||||
|
COPY ./gradle.properties ./
|
||||||
|
COPY ./settings.gradle ./
|
||||||
|
COPY ./gradle/libs.versions.toml ./gradle/
|
||||||
|
RUN gradle bootJar --no-daemon
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------- #
|
||||||
|
FROM alpine/java:21-jdk AS run
|
||||||
|
|
||||||
|
RUN mkdir -p /logs
|
||||||
|
|
||||||
|
RUN adduser --system appuser
|
||||||
|
|
||||||
|
COPY --from=builder --chown=appuser:appuser /build/libs/kontor-spring-0.2.0-SNAPSHOT.jar app.jar
|
||||||
|
RUN chown appuser:root /logs
|
||||||
|
|
||||||
|
EXPOSE 8100
|
||||||
|
USER appuser
|
||||||
CMD ["java", "-jar", "-Dspring.profiles.active=prod", "-Dvaadin.productionMode=true", "app.jar"]
|
CMD ["java", "-jar", "-Dspring.profiles.active=prod", "-Dvaadin.productionMode=true", "app.jar"]
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
|
||||||
<property name="LOGS" value="./logs" />
|
<property name="LOGS" value="logs" />
|
||||||
|
|
||||||
<appender name="Console"
|
<appender name="Console"
|
||||||
class="ch.qos.logback.core.ConsoleAppender">
|
class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
|||||||
Reference in New Issue
Block a user