You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This project is currently used to generate the docker image for hapiproject/hapi
It uses gcr.io/distroless/java17-debian12:nonroot as its base.
It also defaults to exposing the actuator health end point to allow the status to be tested.
This is nice, but when you go looking for help with how to use these endpoints as the health check for the docker container you see posts which nearly always involve curl or wget. But the distroless image does not contain either of these utilities by design.
I would like to propose the inclusion of a special distroless health check class which would be included in the application jar and can be run as the health check command in the docker build file or in the docker compose file.
This would look something like this:
packageca.uhn.fhir.jpa.starter.util;
importcom.fasterxml.jackson.core.type.TypeReference;
importcom.fasterxml.jackson.databind.ObjectMapper;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.beans.factory.annotation.Value;
importorg.springframework.boot.SpringApplication;
importorg.springframework.boot.SpringBootConfiguration;
importorg.springframework.boot.WebApplicationType;
importorg.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
importorg.springframework.boot.context.event.ApplicationReadyEvent;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.event.EventListener;
importorg.springframework.stereotype.Component;
importjava.net.URI;
importjava.net.http.HttpClient;
importjava.net.http.HttpRequest;
importjava.net.http.HttpResponse;
importjava.util.Map;
@ConditionalOnProperty(name = "loader.main", havingValue = "ca.uhn.fhir.jpa.starter.util.DistrolessHealthCheck")
@SpringBootConfigurationpublicclassDistrolessHealthCheck {
privatestaticfinalorg.slf4j.LoggerLOGGER = org.slf4j.LoggerFactory.getLogger(DistrolessHealthCheck.class);
publicstaticvoidmain(String[] args) {
SpringApplicationapplication = newSpringApplication(DistrolessHealthCheck.class);
application.setWebApplicationType(WebApplicationType.NONE);
application.run(args);
}
@ConditionalOnProperty(name = "loader.main", havingValue = "ca.uhn.fhir.jpa.starter.util.DistrolessHealthCheck")
@ComponentstaticclassHealthCheck {
privatefinalApplicationContextappContext;
privatefinalURIhealthUri;
publicHealthCheck(
@AutowiredApplicationContextappContext,
@Value("${server.port:8080}") intdefaultPort,
@Value("${management.server.port:#{null}}") IntegermanagementPort,
@Value("${management.ssl.enabled:false}") booleansslEnabled,
@Value("${management.context-path:/actuator}") StringmanagementContextPath,
@Value("${endpoints.health.path:/health}") StringhealthEndpoint,
@Value("${health.check.uri:#{null}}") URIoverrideURI
) {
this.appContext = appContext;
if (overrideURI != null) {
this.healthUri = overrideURI;
}
else {
// try to workout the health endpoint url using propertiesthis.healthUri = URI.create(
(sslEnabled ? "https" : "http") + "://localhost:" +
(managementPort == null ? defaultPort : managementPort) +
managementContextPath + healthEndpoint);
}
}
@EventListener(ApplicationReadyEvent.class)
publicvoiddoSomethingAfterStartup() {
System.exit(SpringApplication.exit(appContext, this::doHealthCheck));
}
publicintdoHealthCheck() {
intexitCode = 1;
LOGGER.info("Starting health check on port {}", healthUri);
HttpClientclient = HttpClient.newHttpClient();
HttpRequestrequest = HttpRequest.newBuilder()
.uri(healthUri)
.header("accept", "application/json")
.build();
HttpResponse<String> response;
try {
response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
// health check may contain the status of multiple components.// we just want the main statusObjectMappermapper = newObjectMapper();
try {
Map<String, Object> responseMap = mapper.readValue(response.body(),
newTypeReference<Map<String, Object>>() {});
if (responseMap.containsKey("status") && responseMap.get("status").equals("UP")) {
LOGGER.info("Health check passed");
exitCode = 0;
}
else {
LOGGER.error("Health check failed with status {}", responseMap.get("status"));
}
} catch (Throwablet) {
LOGGER.error("Health check failed to parse response", t);
}
}
else {
LOGGER.error("Health check failed with status code {}", response.statusCode());
}
} catch (Throwablet) {
LOGGER.error("Health check failed", t);
}
returnexitCode;
}
}
}
This would try to use the same properties as the main application to determine the healthcheck endpoint and parse its response.
I could supply a pull request with this code, but I'm not sure if people would want the health check in the base docker image and I don't know if there are other obvious issues with this solution.
What is the recommended way to add a health check to the hapi server docker image?
The text was updated successfully, but these errors were encountered:
This project is currently used to generate the docker image for hapiproject/hapi
It uses gcr.io/distroless/java17-debian12:nonroot as its base.
It also defaults to exposing the actuator health end point to allow the status to be tested.
This is nice, but when you go looking for help with how to use these endpoints as the health check for the docker container you see posts which nearly always involve curl or wget. But the distroless image does not contain either of these utilities by design.
I would like to propose the inclusion of a special distroless health check class which would be included in the application jar and can be run as the health check command in the docker build file or in the docker compose file.
This would look something like this:
This would try to use the same properties as the main application to determine the healthcheck endpoint and parse its response.
You would either add
to the main Docker build file, or give instruction for the docker compose to include
I could supply a pull request with this code, but I'm not sure if people would want the health check in the base docker image and I don't know if there are other obvious issues with this solution.
What is the recommended way to add a health check to the hapi server docker image?
The text was updated successfully, but these errors were encountered: