# Discovery

How the agent finds services and suggests checks.

The agent discovers services at startup and hourly. The host's **Discovered** list shows
what no service covers yet. Nothing is monitored until you add it.

## Sources

| Source | What the agent reads |
|---|---|
| Docker or Podman | Containers, images, and published host ports |
| Traefik | Container labels `traefik.http.routers.<router>.*`: host names in `rule`, a path from a single `Path` or `PathPrefix`, the scheme from `tls` and `entrypoints`, and auth from `middlewares` |
| caddy-docker-proxy | Site addresses in container labels `caddy` and `caddy_<n>`, and their `basicauth`, `basic_auth`, and `forward_auth` directives |
| Caddy | Running configuration from the admin API at `127.0.0.1:2019` |
| nginx | `server_name` in `/etc/nginx/sites-enabled/*` and `/etc/nginx/conf.d/*.conf` |
| systemd | Loaded, running services with a unit file in `/etc/systemd/system` or a listening TCP port |
| Listening ports | TCP listeners from `/proc/net/tcp` and `/proc/net/tcp6` |

Wildcards, regular expressions, variables, and placeholder host names are skipped. A
container labelled `traefik.enable=false` gives no Traefik hosts; without that label it
counts as enabled, whatever Traefik's `exposedByDefault` is. Discovery does not read the
Traefik API, Apache or HAProxy configuration, or UDP ports. Matching a port to another
user's process needs access to its `/proc/<pid>/fd` ([Permissions](https://docs.kogut.dev/agent/permissions/)).

Operating-system services and inactive units without a site or listening port are hidden
under **Show all**.

## Proxy URLs

For each Traefik router, the agent builds a URL from the first plain `Host` in its
rule. The URL gets a path only when the rule has exactly one `Path` or `PathPrefix`
joined with `&&`, not negated and not alongside `||` or `HostRegexp`. The scheme is:

- HTTPS when the router sets `tls`, `tls.certresolver`, `tls.options`, or `tls.domains`,
  or when its entrypoints include `websecure`, `https`, or a name with `443`.
- HTTP when it names only the `web` or `http` entrypoints and no TLS.
- HTTPS when it names no entrypoints and no TLS.

Routers that only redirect, through a `redirectscheme` middleware or the
`noop@internal` service, give no URL. A router is protected when one of its
middlewares is defined on the container as `basicauth`, `digestauth`, or `forwardauth`,
directly or inside a `chain`. Only references without a provider or with `@docker` or
`@swarm` use the container's definitions. For middlewares defined elsewhere, such as
`name@file`, a name with `auth` counts as a login service, and one that also has `basic`
or `digest` counts as basic auth.

caddy-docker-proxy site addresses give HTTPS URLs, or HTTP for `http://` addresses and
port 80. A site with a `basicauth`, `basic_auth`, or `forward_auth` directive is
protected.

A container with several URLs suggests one: an unprotected one first, then HTTPS, then
the shortest path, then by router name.

## Monitoring suggestions

For admins, **Monitor** opens a dialog with the proposed service and check. Saving creates
both and associates the service with the host:

- A container with a proxy URL gets an HTTP check of that URL from the kogut server.
  HTTPS URLs include certificate monitoring.
- A site, or a container with domains but no URL, gets an HTTPS check of the first
  domain, including certificate monitoring.
- A port gets a TCP check of `127.0.0.1:<port>` from the host's agent.

Behind basic or digest auth the check expects status `401`. Behind a login service the
dialog warns that the check would test the login page; point it at a health path the
login service lets through, or check the port from the agent.

Older agents send only domains, so the panel suggests HTTPS for the first domain.

The result appears under **Runs here**. **Use kogut.toml instead** gives a configuration
snippet; services managed in the file are changed there. **Dismiss** hides a suggestion
for later discovery runs.

Checks proposed over [MCP](https://docs.kogut.dev/reference/mcp/#drafts) with `draft_check` appear below
the suggestions, under **Proposed checks**, when their `from` is this host, and on the
Overview. An admin approves or rejects each one.

## Service matching

On a host, a container or unit belongs to a service when its name matches, starts with
the service name followed by `-` or `_`, or serves one of the service's sites. Incident
evidence and log requests use their own rules: see
[Correlation](https://docs.kogut.dev/incidents/correlation/) and [agent logs](https://docs.kogut.dev/agent/permissions/#agent-data).

## Missing results

- Missing containers usually mean no access to the container API
  ([Permissions](https://docs.kogut.dev/agent/permissions/)).
- Caddy discovery needs its admin API at `127.0.0.1:2019`; a Docker agent needs host
  networking to reach it.
- nginx discovery needs readable files in the paths above; a Docker agent needs the
  host-root mount from [Docker](https://docs.kogut.dev/agent/docker/).
- A failed source does not stop the others. The agent's log has its error.
