{"id":13839342,"url":"https://github.com/stakater/Xposer","last_synced_at":"2025-07-11T03:32:03.934Z","repository":{"id":34996854,"uuid":"151092365","full_name":"stakater/Xposer","owner":"stakater","description":"A Kubernetes controller to manage (create/update/delete) Kubernetes Ingresses based on the Service - [✩Star] if you are using it!","archived":false,"fork":false,"pushed_at":"2023-12-16T14:20:38.000Z","size":160,"stargazers_count":32,"open_issues_count":6,"forks_count":11,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-08-05T17:23:35.171Z","etag":null,"topics":["expose","ingress","routes","stakater"],"latest_commit_sha":null,"homepage":"https://stakater.com/opensource","language":"Go","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/stakater.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-01T13:22:47.000Z","updated_at":"2024-03-29T08:03:23.000Z","dependencies_parsed_at":"2024-01-18T09:04:33.345Z","dependency_job_id":"aee1f96b-52cc-4063-a682-8840110b0e40","html_url":"https://github.com/stakater/Xposer","commit_stats":{"total_commits":75,"total_committers":7,"mean_commits":"10.714285714285714","dds":"0.42666666666666664","last_synced_commit":"50a4694154873ef293f36e40c7d02b5e081a3bbd"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stakater%2FXposer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stakater%2FXposer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stakater%2FXposer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stakater%2FXposer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stakater","download_url":"https://codeload.github.com/stakater/Xposer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225675073,"owners_count":17506273,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["expose","ingress","routes","stakater"],"created_at":"2024-08-04T17:00:19.537Z","updated_at":"2024-11-21T04:30:36.163Z","avatar_url":"https://github.com/stakater.png","language":"Go","funding_links":[],"categories":["NetWork","Operators vs Controllers"],"sub_categories":["Ingress"],"readme":"# ![](assets/web/xposer-round-100px.png) Xposer\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/stakater/xposer?style=flat-square)](https://goreportcard.com/report/github.com/stakater/xposer)\n[![Go Doc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/stakater/xposer)\n[![Release](https://img.shields.io/github/release/stakater/xposer.svg?style=flat-square)](https://github.com/stakater/xposer/releases/latest)\n[![GitHub tag](https://img.shields.io/github/tag/stakater/xposer.svg?style=flat-square)](https://github.com/stakater/xposer/releases/latest)\n[![Docker Pulls](https://img.shields.io/docker/pulls/stakater/xposer.svg?style=flat-square)](https://hub.docker.com/r/stakater/xposer/)\n[![Docker Stars](https://img.shields.io/docker/stars/stakater/xposer.svg?style=flat-square)](https://hub.docker.com/r/stakater/xposer/)\n[![MicroBadger Size](https://img.shields.io/microbadger/image-size/stakater/xposer.svg?style=flat-square)](https://microbadger.com/images/stakater/xposer)\n[![MicroBadger Layers](https://img.shields.io/microbadger/layers/stakater/xposer.svg?style=flat-square)](https://microbadger.com/images/stakater/xposer)\n[![license](https://img.shields.io/github/license/stakater/xposer.svg?style=flat-square)](LICENSE)\n[![Get started with Stakater](https://stakater.github.io/README/stakater-github-banner.png)](http://stakater.com/?utm_source=Xposer\u0026utm_medium=github)\n\n## Problem\nWe would like to watch for services running in our cluster; and create Ingresses and generate TLS certificates automatically (optional)\n\n## Solution\n\nXposer can watch for all the services running in our cluster; Creates, Updates, Deletes Ingresses and uses certmanager to generate TLS certificates automatically based on some annotations.\n\n## Deploying to Kubernetes\n\nXposer works perfectly fine with default properties. You can however provide custom propeties to change values accordingly\n\n### Vanialla Manifests\n\nYou can apply vanilla manifests by running the following command\n\n```\nkubectl apply -f https://raw.githubusercontent.com/stakater/Xposer/master/deployments/kubernetes/xposer.yaml\n```\n\nXposer by default looks for Services only in the namespace where it is deployed, but it can be managed to work globally, you would have to change the KUBERNETES_NAMESPACE environment variable to \"\" in the above manifest. e.g. change KUBERNETES_NAMESPACE section to:\n\n```\n   - name: KUBERNETES_NAMESPACE\n     value: \"\"\n```\n\nIn Role `xposer-role` change  \n\n```\nkind: Role\n```\n\nto \n\n```\nkind: ClusterRole\n```\n\nIn RoleBinding `xposer-role-binding` change\n\n```\nkind: RoleBinding\nroleRef:\n  kind: Role\n```\n\nto\n\n```\nkind: ClusterRoleBinding\nroleRef:\n  kind: ClusterRole\n```\n\nIf you want Xposer to expose service URLs globally you also need to do the following:\n\nIn Role `xposer-configmap-role` change\n\n```\nkind: Role\n```\n\nto \n\n```\nkind: ClusterRole\n```\n\nIn RoleBinding `xposer-configmap-role-binding` change\n\n```\nkind: RoleBinding\nroleRef:\n  kind: Role\n```\n\nto \n\n```\nkind: ClusterRoleBinding\nroleRef:\n  kind: ClusterRole\n```\n\n### Helm Charts\n\nAlternatively if you have configured helm on your cluster, you can add Xposer to helm from our public chart repository and deploy it via helm using below mentioned commands\n\n```\nhelm repo add stakater https://stakater.github.io/stakater-charts\n\nhelm repo update\n\nhelm install stakater/xposer\n```\n\nBy default Xposer runs in a single namespace where it is deployed. To make Xposer watch all namespaces change the following flag to `true` in `values.yaml` file \n\n```\n  watchGlobally: true\n```\n\nBy default Xposer exposes service URLs locally (service's namespace). To make Xposer expose service URLs globally (in all namespaces) change the following flag to `globally` in `values.yaml` file\n```\n  exposeServiceURL: globally\n```\n\n## How to use Xposer\n\n### Config\nThe default config of Xposer is located at /configs/config.yaml\n\n```\ndomain: stakater.com\ningressURLTemplate: \"{{.Service}}.{{.Namespace}}.{{.Domain}}\"\ningressURLPath: /\ningressNameTemplate: \"{{.Service}}\"\ntls: false\n```\n\nEach property is explained below in details\n\nFor Xposer to  work on your service, it must have a label \"expose = true\"\n\n```bash\nkind: Service\napiVersion: v1\nmetadata:\n  labels:\n    expose: 'true'\n```\n\n### Kubernetes\n\n#### Ingresses\n\nXposer reads the following annotations from a service\n```bash\nkind: Service\napiVersion: v1\nmetadata:\n  labels:\n    expose: 'true'\n  annotations:\n    xposer.stakater.com/annotations: |-\n       firstAnnotation : abc\n       secondAnnotation: abc\n       thirdAnnotation: abc\n```\n`xposer.stakater.com/annotations` accepts annotations in new line. All the annotations provided here will be forwarded to Ingress as it is.\n\n```bash\nkind: Service\napiVersion: v1\nmetadata:\n  labels:\n    expose: 'true'\n  annotations:\n    config.xposer.stakater.com/IngressNameTemplate: \"{{.Service}}-{{.Namespace}}\"\n    config.xposer.stakater.com/IngressURLTemplate: \"{{.Service}}.{{.Domain}}\"\n    config.xposer.stakater.com/IngressURLPath: \"/\"\n    config.xposer.stakater.com/Domain: domain.com\n    config.xposer.stakater.com/TLS: \"true\"\n```\nThe above 5 annotations are used to generate Ingress, if not provided default annotations from /configs/config.yaml will be used. 3 variables used are:\n\n| Variables        | Purpose           |\n| ------------- |:-------------:|\n| `{{.Service}}` | Name of the service which is created/updated |\n| `{{.Namespace}}` | Namespace in which service is created/updated |\n| `{{.Domain}}` | Value from the annotation `config.xposer.stakater.com/Domain` or default domain from /configs/config.yaml file|\n\nThe below 5 annotations are for the following purpose:\n\n| Annotations        | Purpose           |\n| ------------- |:-------------:|\n| `config.xposer.stakater.com/IngressNameTemplate` | With this annotation we can templatize generated Ingress Name. We can use the following template variables as well {{.Service}}, {{.Namespace}}. Can not include domain in Ingress name. | \n| `config.xposer.stakater.com/IngressURLTemplate` | With this annotation we can templatize generated Ingress URL/Hostname. We can use all 3 variables to templatize it |\n| `config.xposer.stakater.com/IngressURLPath` | With this annotation we can specify Ingress Path |\n| `config.xposer.stakater.com/Domain` | With this annotation we can specify domain| \n| `config.xposer.stakater.com/TLS` | With this annotation we can specify wether to use certmanager and generate a TLS certificate or not | \n\n#### Exposing public URL of service\n\nXposer provides support for exposing service's public Url in the form of configmaps. By default it exposes URLs locally (in the same namespace where service is created/updated). Whenever a service is created/updated/deleted, it updates the configmap `xposer` with the Ingress URL of the service. To make it work globally (in all namespaces) please check the following section *Deploying to Kubernetes* to configure Xposer\n\nOn each service which is being exposed by Xposer, we need to add the following annotation under the xposer annotations (The annotations which are forwarded to Ingress)\n\n```\nxposer.stakater.com/annotations: |-\n   exposeIngressUrl: [locally or globally]\n```\n\nThe above annotation can have 2 values; `globally` or `locally`. Any other value will be discarded.\n\nIn case `exposeIngressUrl` was set `globally`, a config-map with name `xposer` will be created in all the namespaces with data like this: \n\n| Key        | Value           |\n| ------------- |:-------------:|\n| `[created-service-name]`-`[created-service-namespace]` | Ingress host of created service | \n\n\nIn case `exposeIngressUrl` was set `locally`, a config-map with name `xposer` will be created only in the current namespace where service is being created/updated\n\n| Key        | Value           |\n| ------------- |:-------------:|\n| `[created-service-name]`-`[created-service-namespace]` | Ingress host of created service | \n\nIn case the service is deleted, they key is removed from configmap\n\n#### Certmanager (Optional)\n\nFirst of all you need to install `certmanager`, and a `Issuer/ClusterIssuer` in your cluster. Xposer only needs 2 annotations to generate TLS certificates\n\n```bash\nkind: Service\napiVersion: v1\nmetadata:\n  labels:\n    expose: 'true'\n  annotations:\n    config.xposer.stakater.com/TLS: \"true\"\n    xposer.stakater.com/annotations: |-\n       certmanager.k8s.io/cluster-issuer: your-cluster-issuer-name\n```\n\nThe above example use cluster issuer `certmanager.k8s.io/cluster-issuer:` annotation which will be forwaded to the ingress as it is with the installed issuer/cluster issuer name. \n\nThe second annotation `config.xposer.stakater.com/TLS:` tells Xposer to add TLS information to the Ingress so it can communicate with the certmanager to generate certificates\n\n### Openshift\n\nSupport for openshift routes will be added soon\n\n## Help\n\n**Got a question?**\nFile a GitHub [issue](https://github.com/stakater/Xposer/issues), or send us an [email](mailto:stakater@gmail.com).\n\n### Talk to us on Slack\nJoin and talk to us on the #tools-imc channel for discussing Xposer\n\n[![Join Slack](https://stakater.github.io/README/stakater-join-slack-btn.png)](https://stakater-slack.herokuapp.com/)\n[![Chat](https://stakater.github.io/README/stakater-chat-btn.png)](https://stakater.slack.com/messages/CAN960CTG/)\n\n## Contributing\n\n### Bug Reports \u0026 Feature Requests\n\nPlease use the [issue tracker](https://github.com/stakater/Xposer/issues) to report any bugs or file feature requests.\n\n### Developing\n\nPRs are welcome. In general, we follow the \"fork-and-pull\" Git workflow.\n\n 1. **Fork** the repo on GitHub\n 2. **Clone** the project to your own machine\n 3. **Commit** changes to your own branch\n 4. **Push** your work back up to your fork\n 5. Submit a **Pull request** so that we can review your changes\n\nNOTE: Be sure to merge the latest from \"upstream\" before making a pull request!\n\n## Changelog\n\nView our closed [Pull Requests](https://github.com/stakater/Xposer/pulls?q=is%3Apr+is%3Aclosed).\n\n## License\n\nApache2 © [Stakater](http://stakater.com)\n\n## About\n\n`Xposer` is maintained by [Stakater][website]. Like it? Please let us know at \u003chello@stakater.com\u003e\n\nSee [our other projects][community]\nor contact us in case of professional services and queries on \u003chello@stakater.com\u003e\n\n  [website]: http://stakater.com/\n  [community]: https://github.com/stakater/","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstakater%2FXposer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstakater%2FXposer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstakater%2FXposer/lists"}