From bc60017c30471496cca922348f0fc72775ef6368 Mon Sep 17 00:00:00 2001 From: lingniu Date: Wed, 1 Jul 2026 12:14:45 +0800 Subject: [PATCH] deploy: add portainer readiness healthchecks --- Dockerfile | 4 +++ deploy/portainer/docker-compose.yml | 30 +++++++++++++++++++ .../PortainerComposeResourceLimitsTest.java | 24 +++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/Dockerfile b/Dockerfile index 542f07e1..5710c4fe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,10 @@ ENV APP_NAME=${APP_NAME} ENV APP_VERSION=${APP_VERSION} ENV JAVA_OPTS="--sun-misc-unsafe-memory-access=allow" +RUN apt-get update \ + && apt-get install -y --no-install-recommends curl \ + && rm -rf /var/lib/apt/lists/* + WORKDIR /app COPY modules/apps/${APP_NAME}/target/${APP_NAME}.jar /app/app.jar diff --git a/deploy/portainer/docker-compose.yml b/deploy/portainer/docker-compose.yml index 20cc736f..1611d38c 100644 --- a/deploy/portainer/docker-compose.yml +++ b/deploy/portainer/docker-compose.yml @@ -76,6 +76,12 @@ services: - gb32960-ingest-data:/data networks: - vehicle-ingest + healthcheck: + test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:20100/actuator/health/readiness >/dev/null"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 60s jt808-ingest-app: image: crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/jt808-ingest-app:${LINGNIU_IMAGE_VERSION:?set LINGNIU_IMAGE_VERSION} @@ -99,6 +105,12 @@ services: - jt808-ingest-data:/data networks: - vehicle-ingest + healthcheck: + test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:20400/actuator/health/readiness >/dev/null"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 60s yutong-mqtt-app: image: crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/yutong-mqtt-app:${LINGNIU_IMAGE_VERSION:?set LINGNIU_IMAGE_VERSION} @@ -129,6 +141,12 @@ services: - yutong-mqtt-data:/data networks: - vehicle-ingest + healthcheck: + test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:20500/actuator/health/readiness >/dev/null"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 60s vehicle-history-app: image: crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-history-app:${LINGNIU_IMAGE_VERSION:?set LINGNIU_IMAGE_VERSION} @@ -164,6 +182,12 @@ services: - "${VEHICLE_HISTORY_HTTP_PORT:-20200}:20200" networks: - vehicle-ingest + healthcheck: + test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:20200/actuator/health/readiness >/dev/null"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 60s vehicle-analytics-app: image: crpi-85r4m0ackrm3qpje.cn-shanghai.personal.cr.aliyuncs.com/oneos/vehicle-analytics-app:${LINGNIU_IMAGE_VERSION:?set LINGNIU_IMAGE_VERSION} @@ -188,6 +212,12 @@ services: - "${VEHICLE_ANALYTICS_HTTP_PORT:-20300}:20300" networks: - vehicle-ingest + healthcheck: + test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:20300/actuator/health/readiness >/dev/null"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 60s networks: vehicle-ingest: diff --git a/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/PortainerComposeResourceLimitsTest.java b/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/PortainerComposeResourceLimitsTest.java index f9def0a4..caf9b0be 100644 --- a/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/PortainerComposeResourceLimitsTest.java +++ b/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/PortainerComposeResourceLimitsTest.java @@ -39,6 +39,19 @@ class PortainerComposeResourceLimitsTest { assertServiceMemoryLimit(compose, "vehicle-analytics-app", "VEHICLE_ANALYTICS_MEM_LIMIT", "1024m"); } + @Test + void portainerServicesUseContainerReadinessHealthchecks() throws IOException { + String compose = Files.readString(repositoryRoot().resolve("deploy/portainer/docker-compose.yml")); + String dockerfile = Files.readString(repositoryRoot().resolve("Dockerfile")); + + assertThat(dockerfile).contains("apt-get install -y --no-install-recommends curl"); + assertServiceReadinessHealthcheck(compose, "gb32960-ingest-app", "20100"); + assertServiceReadinessHealthcheck(compose, "jt808-ingest-app", "20400"); + assertServiceReadinessHealthcheck(compose, "yutong-mqtt-app", "20500"); + assertServiceReadinessHealthcheck(compose, "vehicle-history-app", "20200"); + assertServiceReadinessHealthcheck(compose, "vehicle-analytics-app", "20300"); + } + @Test void containerDefaultsIncludeJava25UnsafeCompatibilityFlag() throws IOException { String compose = Files.readString(repositoryRoot().resolve("deploy/portainer/docker-compose.yml")); @@ -382,6 +395,17 @@ class PortainerComposeResourceLimitsTest { .contains(" mem_limit: ${" + envName + ":-" + defaultLimit + "}"); } + private static void assertServiceReadinessHealthcheck(String compose, String serviceName, String httpPort) { + assertThat(serviceBlock(compose, serviceName)) + .contains(" healthcheck:\n") + .contains(" test: [\"CMD-SHELL\", \"curl -fsS http://127.0.0.1:" + + httpPort + "/actuator/health/readiness >/dev/null\"]") + .contains(" interval: 30s\n") + .contains(" timeout: 5s\n") + .contains(" retries: 3\n") + .contains(" start_period: 60s\n"); + } + private static String serviceBlock(String compose, String serviceName) { String marker = "\n " + serviceName + ":\n"; int start = compose.indexOf(marker);