Skip to content

Fix container HEALTHCHECK when port 0 is used in confguration #524

@josecelano

Description

@josecelano

Context

We have a HEALTHCHECK instruction in the Containerfile:

HEALTHCHECK --interval=5s --timeout=5s --start-period=3s --retries=3 \  
  CMD /usr/bin/http_health_check http://localhost:${HEALTH_CHECK_API_PORT}/health_check \
    || exit 1

The implementation is here. It checks that all services are running:

  • API
  • 1 or more HTTP trackers
  • 1 or more UDP trackers

For the API, for example, it tries to connect to the API healthcheck endpoint.

async fn api_health_check(config: &HttpApi) -> Option<Json<Report>> {
    // todo: when port 0 is specified in the configuration get the port from the
    // running service, after starting it as we do for testing with ephemeral
    // configurations.

    if config.enabled {
        let addr: SocketAddr = config.bind_address.parse().expect("invalid socket address for API");

        if addr.port() != UNKNOWN_PORT {
            let health_check_url = format!("http://{addr}/health_check");

            if !get_req_is_ok(&health_check_url).await {
                return Some(responses::error(format!(
                    "API is not healthy. Health check endpoint: {health_check_url}"
                )));
            }
        }
    }

    None
}

In the API configuration (Config.toml):

[http_api]
bind_address = "127.0.0.1:1212"
enabled = true
#...

you can specify the port = like this:

[http_api]
bind_address = "127.0.0.1:0"
enabled = true
#...

In that case, the application will assign a free port.

Problem

The healthcheck endpoint relies on static configuration. If you use port 0 the healthcheck skippies that service. We need to pass the list of actual ports to the "healthchecker" instead of the configuration.

Solution

When we run the services we have to send back the port used to the main app. And the main app has to inject that configuration (list of services and ports) to the "healthchecker".

Relates To

Metadata

Metadata

Assignees

Labels

- Admin -Enjoyable to Install and Setup our Software- Developer -Torrust Improvement ExperienceBlockedHas Unsatisfied Dependency or blocked by a contributor.Quality & AssuranceRelates to QA, Testing, and CI

Type

No type

Projects

Status

Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions