{"id":46513822,"url":"https://github.com/canonical/traefik-k8s-operator","last_synced_at":"2026-03-16T10:09:04.123Z","repository":{"id":36954436,"uuid":"449338273","full_name":"canonical/traefik-k8s-operator","owner":"canonical","description":"This charmed operator automates the operational procedures of running Traefik, an open-source application proxy.","archived":false,"fork":false,"pushed_at":"2026-03-05T11:00:03.000Z","size":27316,"stargazers_count":15,"open_issues_count":71,"forks_count":43,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-03-05T15:17:52.851Z","etag":null,"topics":["charm","platform-engineering","product-kubernetes-ingress","squad-emea"],"latest_commit_sha":null,"homepage":"https://charmhub.io/traefik-k8s","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/canonical.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-18T15:24:13.000Z","updated_at":"2026-02-27T05:19:06.000Z","dependencies_parsed_at":"2024-05-21T11:19:04.510Z","dependency_job_id":null,"html_url":"https://github.com/canonical/traefik-k8s-operator","commit_stats":null,"previous_names":[],"tags_count":206,"template":false,"template_full_name":"canonical/template-operator","purl":"pkg:github/canonical/traefik-k8s-operator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canonical%2Ftraefik-k8s-operator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canonical%2Ftraefik-k8s-operator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canonical%2Ftraefik-k8s-operator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canonical%2Ftraefik-k8s-operator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/canonical","download_url":"https://codeload.github.com/canonical/traefik-k8s-operator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/canonical%2Ftraefik-k8s-operator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30186780,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T14:42:24.748Z","status":"ssl_error","status_checked_at":"2026-03-06T14:42:14.925Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["charm","platform-engineering","product-kubernetes-ingress","squad-emea"],"created_at":"2026-03-06T17:03:49.559Z","updated_at":"2026-03-16T10:09:04.115Z","avatar_url":"https://github.com/canonical.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Traefik Kubernetes Charmed Operator\n\n[![CharmHub Badge](https://charmhub.io/traefik-k8s/badge.svg)](https://charmhub.io/traefik-k8s)\n[![Release](https://github.com/canonical/traefik-k8s-operator/actions/workflows/release.yaml/badge.svg)](https://github.com/canonical/traefik-k8s-operator/actions/workflows/release.yaml)\n[![Discourse Status](https://img.shields.io/discourse/status?server=https%3A%2F%2Fdiscourse.charmhub.io\u0026style=flat\u0026label=CharmHub%20Discourse)](https://discourse.charmhub.io)\n\nThis [Juju](https://juju.is) charmed operator written with the [Operator Lifecycle Manager Framework](https://juju.is/docs/olm), powering _ingress controller-like_ capabilities on Kubernetes.\nBy _ingress controller-like_ capabilities, we mean that the Traefik Kubernetes charmed operator exposes Juju applications to the outside of a Kubernetes cluster, **without** relying on the [`ingress` resource](https://kubernetes.io/docs/concepts/services-networking/ingress/) of Kubernetes.\nRather, Traefik is instructed to expose Juju applications by means of relations with them.\n\n## Setup\n\nThese instructions assume you will run the charm on [`microk8s`](https://microk8s.io), and rely on a few plugins, specifically:\n\n```sh\nsudo snap install microk8s\nmicrok8s enable storage dns\n# The following line is required unless you plan to use the `external_hostname` configuration option\nmicrok8s enable metallb 192.168.0.10-192.168.0.100 # You likely want change these IP ranges\n```\n\n## Usage\n\n```sh\njuju deploy ./traefik-k8s_ubuntu-20.04-amd64.charm traefik-ingress --trust --resource traefik-image=ghcr.io/canonical/traefik:2.10.4\n```\n\n## Configurations\n\n* `external_hostname` allows you to specify a host for the URL that Traefik will assume is its externally-visible URL, and that will be used to generate the URLs passed to the proxied applications. Note that this has to be a 'bare' hostname, i.e. no `http` prefix and no `:port` suffix. Neither are configurable at the moment.\n  If `external_hostname` is unspecified, Traefik will use the ingress ip of its Kubernetes service, and the charm will go into `WaitingStatus` if it does not discover an ingress IP on its Kubernetes service.\n  The [Setup](#setup) section shows how to optionally set up `metallb` with MicroK8s, so that Traefik's Kubernetes service will receive an ingress IP.\n\n* `routing_mode`: structured as an enumeration, that allows you to select how Traefik will generate routes:\n  * `path`: Traefik will use its externally-visible url and create a route for the requester that will be structure like:\n\n    ```\n    http://\u003cexternal_hostname\u003e:\u003cport\u003e/\u003crequester_model_name\u003e-\u003crequester_application_name\u003e-\u003crequester-unit-index\u003e\n    ```\n\n    For example, an ingress-per-unit provider with `http://foo` external URL, will provide to the unit `my-unit/2` in the `my-model` model the following URL:\n\n    ```\n    http://foo/my-model-my-unit-2\n    ```\n\n  * `subdomain`: Traefik will use its externally-visible url, based on `external_hostname` or, missing that, the ingress IP, and create a route for the requester that will be structure like:\n\n    ```\n    http://\u003crequester_model_name\u003e-\u003crequester_application_name\u003e-\u003crequester-unit-index\u003e.\u003cexternal_hostname\u003e:\u003cport\u003e/\n    ```\n\n    For example, an ingress-per-unit provider with `http://foo:8080` external URL, will provide to the unit `my-unit/2` in the `my-model` model the following URL:\n\n    ```\n    http://my-model-my-unit-2.foo:8080\n    ```\n\n    **IMPORTANT:** With the `subdomain` routing mode, incoming HTTP requests have the `Host` header set to match one of the routes.\n    Considering the example above, incoming requests are expected to have the following HTTP header:\n\n    ```\n    Host: my-model-my-unit-2.foo\n    ```\n\n## Relations\n\n### Providing ingress proxying\n\nThis charmed operator supports two types of proxying:\n\n* `per-app`: This is the \"classic\" proxying logic of an ingress-controller, load-balancing incoming connections to the various units of the Juju application related via the `ingress` relation by routing over the latter's Kubernetes service.\n* `per-unit`: Traefik will have routes to the single pods of the proxied Juju application related to it via the `ingress-per-unit` relation.\n  This type of routing, while somewhat unconventional in Kubernetes, is necessary for applications like Prometheus (where each remote-write endpoint needs to be routed to separately) and beneficial to databases, the clients of which can perform client-side load balancing\n\n### Monitoring Traefik itself\n\nThe metrics endpoint exposed by Traefik can be scraped by Prometheus over the [`prometheus_scrape` relation interface](https://charmhub.io/prometheus-k8s/libraries/prometheus_scrape) with:\n\n```sh\njuju add-relation traefik-ingress:metrics-endpoint prometheus\n```\n\n## Documentation\n\nOur documentation is stored in the `docs` directory.\nIt is based on the Canonical starter pack\nand hosted on [Read the Docs](https://about.readthedocs.com/). In structuring,\nthe documentation employs the [Diátaxis](https://diataxis.fr/) approach.\n\nYou may open a pull request with your documentation changes, or you can\n[file a bug](https://github.com/canonical/traefik-k8s-operator/issues) to provide constructive feedback or suggestions.\n\nTo run the documentation locally before submitting your changes:\n\n```bash\ncd docs\nmake run\n```\n\nGitHub runs automatic checks on the documentation\nto verify spelling, validate links and style guide compliance.\n\nYou can (and should) run the same checks locally:\n\n```bash\nmake spelling\nmake linkcheck\nmake vale\nmake lint-md\n```\n\n## Contributing\n\nPlease see the [Juju SDK docs](https://juju.is/docs/sdk) for guidelines on enhancements to this charm following best practice guidelines, and [CONTRIBUTING.md](https://github.com/canonical/traefik-k8s-operator/blob/main/CONTRIBUTING.md) for developer guidance.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanonical%2Ftraefik-k8s-operator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcanonical%2Ftraefik-k8s-operator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcanonical%2Ftraefik-k8s-operator/lists"}