Search code examples
javadockermavendocker-maven-pluginfabric8-maven-plugin

Docker healthcheck command always returns healthy


I am using the docker-maven-plugin. I am building a Docker container containing a Java command line application.

In my healthcheck I am checking that a Java process matching a name exists:

<healthCheck>
  <cmd>pgrep -f "java.*my-app-name.*jar" > /dev/null || exit 1</cmd>
</healthCheck>

The problem is, this always returns healthy. For example, if I change it to something that should not be healthy:

<healthCheck>
  <cmd>pgrep -f "DOES-NOT-EXIST" > /dev/null || exit 1</cmd>
</healthCheck>

and run docker ps, the container is reporting as healthy:

enter image description here

This is the output of docker images <IMAGE ID>:

            "Healthcheck": {
                "Test": [
                    "CMD-SHELL",
                    "pgrep -f \"DOES-NOT-EXIST\" > /dev/null || exit 1"
                ]
            },

If I log into the running container, the commands look like they are working as expected, so I'm not sure why the container reports as healthy when it should not:

34c68bcd9436:/ # pgrep -f "java.*my-app-name.*jar" > /dev/null || exit 1
34c68bcd9436:/ # pgrep -f "DOES-NOT-EXIST" > /dev/null || exit 1
exit

Here are the healthcheck logs for the container, showing the healthcheck command always returning 0:

docker inspect --format "{{json .State.Health }}" 0f607cf3bbcd | jq
{
  "Status": "healthy",
  "FailingStreak": 0,
  "Log": [
    {
      "Start": "2023-01-18T12:02:48.7530323Z",
      "End": "2023-01-18T12:02:48.921539Z",
      "ExitCode": 0,
      "Output": ""
    },
    {
      "Start": "2023-01-18T12:03:18.9279247Z",
      "End": "2023-01-18T12:03:19.0777841Z",
      "ExitCode": 0,
      "Output": ""
    },
    {
      "Start": "2023-01-18T12:03:49.0825991Z",
      "End": "2023-01-18T12:03:49.1990431Z",
      "ExitCode": 0,
      "Output": ""
    },
    {
      "Start": "2023-01-18T12:04:19.2065635Z",
      "End": "2023-01-18T12:04:19.3829184Z",
      "ExitCode": 0,
      "Output": ""
    },
    {
      "Start": "2023-01-18T12:04:49.3996451Z",
      "End": "2023-01-18T12:04:49.5594201Z",
      "ExitCode": 0,
      "Output": ""
    }
  ]
}

If I change the healthcheck to just this:

<healthCheck>
  <cmd>exit 1</cmd>
</healthCheck>

Then it works as expected and the container reports as unhealthy, so it must be something with the pgrep command?


Solution

  • Moving the command to a script works:

    assembly.xml

    <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3
                                  http://maven.apache.org/xsd/assembly-1.1.3.xsd">
        <dependencySets>
            <dependencySet>
                <includes />
                <useProjectArtifact>false</useProjectArtifact>
            </dependencySet>
        </dependencySets>
        <fileSets>
            <fileSet>
                <directory>${project.basedir}/src/main/docker/</directory>
                <includes>
                    <include>healthcheck.sh</include>
                </includes>
                <fileMode>0755</fileMode>
                <lineEnding>unix</lineEnding>
                <outputDirectory>healthcheck</outputDirectory>
            </fileSet>
        </fileSets>
    </assembly>
    

    healthcheck.sh

    #!/bin/bash
    
    pgrep -f "java.*my-app.*jar" > /dev/null
    

    pom.xml

    <healthCheck>
      <cmd>/maven/healthcheck/healthcheck.sh || exit 1</cmd>
    </healthCheck>