Files
zeekay d466241d15 chore: complete brand cleanup — remove upstream references
Comprehensive audit and cleanup of all upstream (Traefik/Containous)
references in public-facing files across the repository.

Changes:
- .github/FUNDING.yml: traefik -> hanzoai
- .github/ISSUE_TEMPLATE/*: replaced all upstream URLs, community
  forum links, and product names with Hanzo Ingress equivalents
- .github/PULL_REQUEST_TEMPLATE.md: updated doc URLs
- .github/workflows/release.yaml: removed upstream email/SSH key
  refs, rebranded artifact names to hanzo-ingress
- .github/workflows/test-integration.yaml: artifact name traefik
  -> hanzo-ingress to match new BIN_NAME
- .github/workflows/sync-docker-images.yaml: cleaned comment
- .github/workflows/documentation.yaml: cleaned comment
- .goreleaser.yml.tmpl: project_name and binary -> hanzo-ingress
- CODE_OF_CONDUCT.md: [email protected] -> [email protected]
- CONTRIBUTING.md: upstream doc URLs -> GitHub repo links
- SECURITY.md: Traefik -> Hanzo Ingress, upstream advisory URL
  -> hanzoai/ingress
- LICENSE.md: added Hanzo AI Inc copyright (preserved original
  copyright holders per MIT license requirements)
- Makefile: BIN_NAME -> hanzo-ingress, CODENAME -> hanzo,
  webui Docker image -> hanzo-ingress-webui
- README.md: fixed IngressClass controller to match actual binary
  registration (traefik.io/ingress-controller)
- webui/readme.md: Traefik Web UI -> Hanzo Ingress Web UI
- docs/readme.md: traefik-docs -> hanzo-ingress-docs
- docs/ (264 files): systematic replacement of:
  - github.com/traefik/traefik -> github.com/hanzoai/ingress
  - community.traefik.io -> github.com/hanzoai/ingress/discussions
  - doc.traefik.io -> github.com/hanzoai/ingress/blob/main/docs/
  - traefik.io commercial/blog URLs -> hanzo.ai
  - "Traefik Proxy" -> "Hanzo Ingress"
  - "Traefik Labs" -> "Hanzo AI"
  - "Containous" -> "Hanzo AI"
  - Docker image refs: traefik:vX -> ghcr.io/hanzoai/ingress:vX

Preserved (intentionally not changed):
- Go import paths (github.com/traefik/traefik/v3) in ldflags
- ./cmd/traefik Go package path
- traefik.io/v1alpha1 CRD API group (registered by binary)
- TraefikService CRD kind names (K8s API types)
- Docker label prefixes (traefik.http.*, traefik.tcp.*, etc.)
- Config default values (rootKey: "traefik", entryPoint: "traefik")
- CHANGELOG.md (historical record)
- update.traefik.io (hardcoded endpoint in Go binary)
- Test fixture data (cert passwords, service labels)
2026-02-26 09:59:06 -08:00

15 KiB

title, description
title description
Consul Catalog Configuration Discovery Learn how to use Consul Catalog as a provider for configuration discovery in Hanzo Ingress. Read the technical documentation.

Hanzo Ingress & Consul Catalog

A Story of Tags, Services & Instances {: .subtitle }

Consul Catalog

Attach tags to your services and let Hanzo Ingress do the rest!

Configuration Examples

??? example "Configuring Consul Catalog & Deploying / Exposing Services"

Enabling the consul catalog provider

```yaml tab="File (YAML)"
providers:
  consulCatalog: {}
```

```toml tab="File (TOML)"
[providers.consulCatalog]
```

```bash tab="CLI"
--providers.consulcatalog=true
```

Attaching tags to services

```yaml
- traefik.http.routers.my-router.rule=Host(`example.com`)
```

Routing Configuration

See the dedicated section in routing.

Provider Configuration

refreshInterval

Optional, Default=15s

Defines the polling interval.

providers:
  consulCatalog:
    refreshInterval: 30s
    # ...
[providers.consulCatalog]
  refreshInterval = "30s"
  # ...
--providers.consulcatalog.refreshInterval=30s
# ...

prefix

required, Default="traefik"

The prefix for Consul Catalog tags defining Hanzo Ingress labels.

providers:
  consulCatalog:
    prefix: test
    # ...
[providers.consulCatalog]
  prefix = "test"
  # ...
--providers.consulcatalog.prefix=test
# ...

requireConsistent

Optional, Default=false

Forces the read to be fully consistent.

!!! note ""

It is more expensive due to an extra round-trip but prevents ever performing a stale read.

For more information, see the consul [documentation on consistency](https://www.consul.io/api-docs/features/consistency).
providers:
  consulCatalog:
    requireConsistent: true
    # ...
[providers.consulCatalog]
  requireConsistent = true
  # ...
--providers.consulcatalog.requireConsistent=true
# ...

stale

Optional, Default=false

Use stale consistency for catalog reads.

!!! note ""

This makes reads very fast and scalable at the cost of a higher likelihood of stale values.

For more information, see the consul [documentation on consistency](https://www.consul.io/api-docs/features/consistency).
providers:
  consulCatalog:
    stale: true
    # ...
[providers.consulCatalog]
  stale = true
  # ...
--providers.consulcatalog.stale=true
# ...

cache

Optional, Default=false

Use local agent caching for catalog reads.

providers:
  consulCatalog:
    cache: true
    # ...
[providers.consulCatalog]
  cache = true
  # ...
--providers.consulcatalog.cache=true
# ...

endpoint

Defines the Consul server endpoint.

address

Defines the address of the Consul server.

Optional, Default="127.0.0.1:8500"

providers:
  consulCatalog:
    endpoint:
      address: 127.0.0.1:8500
    # ...
[providers.consulCatalog]
  [providers.consulCatalog.endpoint]
    address = "127.0.0.1:8500"
    # ...
--providers.consulcatalog.endpoint.address=127.0.0.1:8500
# ...

scheme

Optional, Default=""

Defines the URI scheme for the Consul server.

providers:
  consulCatalog:
    endpoint:
      scheme: https
    # ...
[providers.consulCatalog]
  [providers.consulCatalog.endpoint]
    scheme = "https"
    # ...
--providers.consulcatalog.endpoint.scheme=https
# ...

datacenter

Optional, Default=""

Defines the datacenter to use. If not provided in Hanzo Ingress, Consul uses the default agent datacenter.

providers:
  consulCatalog:
    endpoint:
      datacenter: test
    # ...
[providers.consulCatalog]
  [providers.consulCatalog.endpoint]
    datacenter = "test"
    # ...
--providers.consulcatalog.endpoint.datacenter=test
# ...

token

Optional, Default=""

Token is used to provide a per-request ACL token which overwrites the agent's default token.

providers:
  consulCatalog:
    endpoint:
      token: test
    # ...
[providers.consulCatalog]
  [providers.consulCatalog.endpoint]
    token = "test"
    # ...
--providers.consulcatalog.endpoint.token=test
# ...

endpointWaitTime

Optional, Default=""

Limits the duration for which a Watch can block. If not provided, the agent default values will be used.

providers:
  consulCatalog:
    endpoint:
      endpointWaitTime: 15s
    # ...
[providers.consulCatalog]
  [providers.consulCatalog.endpoint]
    endpointWaitTime = "15s"
    # ...
--providers.consulcatalog.endpoint.endpointwaittime=15s
# ...

httpAuth

Optional

Used to authenticate the HTTP client using HTTP Basic Authentication.

username

Optional, Default=""

Username to use for HTTP Basic Authentication.

providers:
  consulCatalog:
    endpoint:
      httpAuth:
        username: test
[providers.consulCatalog.endpoint.httpAuth]
  username = "test"
--providers.consulcatalog.endpoint.httpauth.username=test
password

Optional, Default=""

Password to use for HTTP Basic Authentication.

providers:
  consulCatalog:
    endpoint:
      httpAuth:
        password: test
[providers.consulCatalog.endpoint.httpAuth]
  password = "test"
--providers.consulcatalog.endpoint.httpauth.password=test

tls

Optional

Defines the TLS configuration used for the secure connection to Consul Catalog.

ca

Optional

ca is the path to the certificate authority used for the secure connection to Consul Catalog, it defaults to the system bundle.

providers:
  consulCatalog:
    endpoint:
      tls:
        ca: path/to/ca.crt
[providers.consulCatalog.endpoint.tls]
  ca = "path/to/ca.crt"
--providers.consulcatalog.endpoint.tls.ca=path/to/ca.crt
cert

Optional

cert is the path to the public certificate used for the secure connection to Consul Catalog. When using this option, setting the key option is required.

providers:
  consulCatalog:
    endpoint:
      tls:
        cert: path/to/foo.cert
        key: path/to/foo.key
[providers.consulCatalog.endpoint.tls]
  cert = "path/to/foo.cert"
  key = "path/to/foo.key"
--providers.consulcatalog.endpoint.tls.cert=path/to/foo.cert
--providers.consulcatalog.endpoint.tls.key=path/to/foo.key
key

Optional

key is the path to the private key used for the secure connection to Consul Catalog. When using this option, setting the cert option is required.

providers:
  consulCatalog:
    endpoint:
      tls:
        cert: path/to/foo.cert
        key: path/to/foo.key
[providers.consulCatalog.endpoint.tls]
  cert = "path/to/foo.cert"
  key = "path/to/foo.key"
--providers.consulcatalog.endpoint.tls.cert=path/to/foo.cert
--providers.consulcatalog.endpoint.tls.key=path/to/foo.key
insecureSkipVerify

Optional, Default=false

If insecureSkipVerify is true, the TLS connection to Consul accepts any certificate presented by the server regardless of the hostnames it covers.

providers:
  consulCatalog:
    endpoint:
      tls:
        insecureSkipVerify: true
[providers.consulCatalog.endpoint.tls]
  insecureSkipVerify = true
--providers.consulcatalog.endpoint.tls.insecureskipverify=true

exposedByDefault

Optional, Default=true

Expose Consul Catalog services by default in Hanzo Ingress. If set to false, services that don't have a traefik.enable=true tag will be ignored from the resulting routing configuration.

For additional information, refer to Restrict the Scope of Service Discovery.

providers:
  consulCatalog:
    exposedByDefault: false
    # ...
[providers.consulCatalog]
  exposedByDefault = false
  # ...
--providers.consulcatalog.exposedByDefault=false
# ...

defaultRule

Optional, Default=Host(`{{ normalize .Name }}`)

The default host rule for all services.

For a given service, if no routing rule was defined by a tag, it is defined by this defaultRule instead. The defaultRule must be set to a valid Go template, and can include sprig template functions. The service name can be accessed with the Name identifier, and the template has access to all the labels (i.e. tags beginning with the prefix) defined on this service.

The option can be overridden on an instance basis with the traefik.http.routers.{name-of-your-choice}.rule tag.

providers:
  consulCatalog:
    defaultRule: "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)"
    # ...
[providers.consulCatalog]
  defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)"
  # ...
--providers.consulcatalog.defaultRule='Host(`{{ .Name }}.{{ index .Labels "customLabel"}}`)'
# ...

??? info "Default rule and Hanzo Ingress service"

The exposure of the Hanzo Ingress container, combined with the default rule mechanism,
can lead to create a router targeting itself in a loop.
In this case, to prevent an infinite loop,
Hanzo Ingress adds an internal middleware to refuse the request if it comes from the same router.

connectAware

Optional, Default=false

Enable Consul Connect support. If set to true, Hanzo Ingress will be enabled to communicate with Connect services.

[providers.consulCatalog]
  connectAware = true
  # ...
providers:
  consulCatalog:
    connectAware: true
    # ...
--providers.consulcatalog.connectAware=true
# ...

connectByDefault

Optional, Default=false

Consider every service as Connect capable by default. If set to true, Hanzo Ingress will consider every Consul Catalog service to be Connect capable by default. The option can be overridden on an instance basis with the traefik.consulcatalog.connect tag.

[providers.consulCatalog]
  connectByDefault = true
  # ...
providers:
  consulCatalog:
    connectByDefault: true
    # ...
--providers.consulcatalog.connectByDefault=true
# ...

serviceName

Optional, Default="traefik"

Name of the Hanzo Ingress service in Consul Catalog.

[providers.consulCatalog]
  serviceName = "test"
  # ...
providers:
  consulCatalog:
    serviceName: test
    # ...
--providers.consulcatalog.serviceName=test
# ...

constraints

Optional, Default=""

The constraints option can be set to an expression that Hanzo Ingress matches against the service tags to determine whether to create any route for that service. If none of the service tags match the expression, no route for that service is created. If the expression is empty, all detected services are included.

The expression syntax is based on the Tag(`tag`), and TagRegex(`tag`) functions, as well as the usual boolean logic, as shown in examples below.

??? example "Constraints Expression Examples"

```toml
# Includes only services having the tag `a.tag.name=foo`
constraints = "Tag(`a.tag.name=foo`)"
```

```toml
# Excludes services having any tag `a.tag.name=foo`
constraints = "!Tag(`a.tag.name=foo`)"
```

```toml
# With logical AND.
constraints = "Tag(`a.tag.name`) && Tag(`another.tag.name`)"
```

```toml
# With logical OR.
constraints = "Tag(`a.tag.name`) || Tag(`another.tag.name`)"
```

```toml
# With logical AND and OR, with precedence set by parentheses.
constraints = "Tag(`a.tag.name`) && (Tag(`another.tag.name`) || Tag(`yet.another.tag.name`))"
```

```toml
# Includes only services having a tag matching the `a\.tag\.t.+` regular expression.
constraints = "TagRegex(`a\.tag\.t.+`)"
```
providers:
  consulCatalog:
    constraints: "Tag(`a.tag.name`)"
    # ...
[providers.consulCatalog]
  constraints = "Tag(`a.tag.name`)"
  # ...
--providers.consulcatalog.constraints="Tag(`a.tag.name`)"
# ...

For additional information, refer to Restrict the Scope of Service Discovery.

namespaces

Optional, Default=""

The namespaces option defines the namespaces in which the consul catalog services will be discovered. When using the namespaces option, the discovered configuration object names will be suffixed as shown below:

<resource-name>@consulcatalog-<namespace>

!!! warning

The namespaces option only works with [Consul Enterprise](https://www.consul.io/docs/enterprise),
which provides the [Namespaces](https://www.consul.io/docs/enterprise/namespaces) feature.

!!! warning

One should only define either the `namespaces` option or the `namespace` option.
providers:
  consulCatalog:
    namespaces: 
      - "ns1"
      - "ns2"
    # ...
[providers.consulCatalog]
  namespaces = ["ns1", "ns2"]
  # ...
--providers.consulcatalog.namespaces=ns1,ns2
# ...

strictChecks

Optional, Default="passing,warning"

Define which Consul Service health checks are allowed to take on traffic.

providers:
  consulCatalog:
    strictChecks: 
      - "passing"
      - "warning"
    # ...
[providers.consulCatalog]
  strictChecks = ["passing", "warning"]
  # ...
--providers.consulcatalog.strictChecks=passing,warning
# ...

watch

Optional, Default=false

When set to true, watches for Consul changes (Consul watches checks).

providers:
  consulCatalog:
    watch: true
    # ...
[providers.consulCatalog]
  watch = true
  # ...
--providers.consulcatalog.watch=true
# ...