Manage Configuration with GitOps in the Administration UI
GitOps lets you create, edit, and delete AI routes, MCP servers, and HTTP routers, services, and middlewares from the Administration UI. Each change opens a pull request on the GitHub repository that holds your gateway's configuration, under your own GitHub account. Your team reviews and merges the pull request, and your GitOps tool applies it to the cluster.
This guide connects the Administration UI to a repository with a GitHub App, and walks through proposing a change.
Prerequisites
- The Administration UI, installed and running.
- A GitHub repository that holds your gateway's configuration as Kubernetes manifests, as a file provider dynamic
configuration file, or as both. The Administration UI edits the following manifest kinds:
Ingress,IngressRoute,HTTPRoute,Middleware,TraefikService, andService. - A GitOps tool, such as Flux or Argo CD, that applies the merged manifests to your cluster. The Administration UI only opens pull requests. Merging a pull request changes your gateway only when a GitOps tool applies the repository.
- A GitHub account that can write to the repository.
Step 1: Create a GitHub App
The Administration UI uses a GitHub App to read the repository, and to sign users in with their own GitHub accounts. Register the app in the GitHub account or organization that you use to manage your repository. For the full procedure, see Registering a GitHub App.
-
In GitHub, open Settings, then Developer settings, then GitHub Apps, and select New GitHub App.
-
Enter the following fields. Leave the other fields at their defaults.
- GitHub App name: a name of your choice, for example
admin-ui-gitops. - Homepage URL: the URL of your Administration UI, for example
https://admin.example.com. - Callback URL:
<external URL>/api/gitops/callback, for examplehttps://admin.example.com/api/gitops/callback. - Webhook: clear Active.
- Repository permissions: set Contents and Pull requests to Read and write.
- GitHub App name: a name of your choice, for example
-
Select Create GitHub App.
-
In the settings of the new app, collect the credentials that the next steps use:
- Client ID: copy it from the settings page of the app.
- Client secret: under Client secrets, select Generate a new client secret, and copy it. GitHub displays the secret only once.
- Private key: under Private keys, select Generate a private key. GitHub downloads a
.pemfile.
Step 2: Install the GitHub App on the repository
- In the settings of the GitHub App, select Install App.
- Select the account or organization that owns the repository.
- Choose the repositories the app can access. Include the repository that holds your configuration.
- Select Install.
If you skip this step, the rollout in step 4 doesn't complete. Read the log of the new pod for the URL where you can install the app.
Step 3: Store the GitHub App credentials
Create a secret named admin-ui-github that holds the client secret and the private key. Replace <client secret> with
the client secret from step 1, and <path to the .pem file> with the path of the private key you downloaded:
kubectl -n traefik create secret generic admin-ui-github \
--from-literal=clientSecret=<client secret> \
--from-file=privateKey=<path to the .pem file>
Step 4: Configure the Administration UI
-
In your
admin-ui.yaml, add the following environment variables to theadmin-uicontainer:admin-ui.yaml- name: TRAEFIK_HUB_DASHBOARD_GITOPS_REPOSITORYvalue: https://github.com/<owner>/<repository> # Replace with the URL of your repository.- name: TRAEFIK_HUB_DASHBOARD_GITOPS_BASEBRANCHvalue: main # Replace with the branch the pull requests target.- name: TRAEFIK_HUB_DASHBOARD_GITOPS_ROOTvalue: <directory> # Replace with the directory of the manifests in the repository.- name: TRAEFIK_HUB_DASHBOARD_GITOPS_EXTERNALURLvalue: https://admin.example.com # Replace with the URL you use to open the Administration UI.- name: TRAEFIK_HUB_DASHBOARD_GITOPS_GITHUB_CLIENTIDvalue: <client ID> # Replace with the client ID of the GitHub App.- name: TRAEFIK_HUB_DASHBOARD_GITOPS_GITHUB_CLIENTSECRETvalueFrom:secretKeyRef:name: admin-ui-githubkey: clientSecret- name: TRAEFIK_HUB_DASHBOARD_GITOPS_GITHUB_PRIVATEKEYvalue: /etc/admin-ui-github/privateKey -
Add the following to the
volumeMountsof theadmin-uicontainer:admin-ui.yaml- name: github-appmountPath: /etc/admin-ui-githubreadOnly: true -
Add the following to the
volumesof thetraefik-hub-admin-uideployment:admin-ui.yaml- name: github-appsecret:secretName: admin-ui-githubitems:- key: privateKeypath: privateKey -
Replace the placeholder values:
TRAEFIK_HUB_DASHBOARD_GITOPS_ROOT: the directory that holds the manifests. Leave the value empty if the manifests are in the root of the repository.TRAEFIK_HUB_DASHBOARD_GITOPS_EXTERNALURL: the URL you use to open the Administration UI in a browser. It must match the host of the Callback URL from step 1.
-
Apply the manifest and wait for the
traefik-hub-admin-uideployment:kubectl apply -f admin-ui.yamlkubectl -n traefik rollout status deploy/traefik-hub-admin-ui
The pod becomes ready after the Administration UI fetches the repository.
Two optional settings extend this configuration:
- To manage a file provider dynamic configuration file, set
TRAEFIK_HUB_DASHBOARD_GITOPS_FILEPROVIDERCONFIGto the path of the file inside the repository and under the root directory. - For a GitHub Enterprise Server, set
TRAEFIK_HUB_DASHBOARD_GITOPS_GITHUB_URLto the URL of the server.
For every GitOps setting, see the configuration reference.
Step 5: Propose a change
You can create, edit, and delete AI routes, MCP servers, HTTP routers, HTTP services, and HTTP middlewares. The steps are the same for each resource type.
- Open the Administration UI. With GitOps enabled, each list page under AI & MCP and HTTP displays a button to create a resource, such as New AI route. The detail page of a resource that your repository defines displays an Edit button and a menu with Duplicate and Delete.
- Create a resource with the button on its list page, or open an existing resource and select Edit. To delete a resource, open its menu and select Delete.
- Fill in or change the fields. The Source tab beside the form displays the generated file, and the Changes tab displays the diff of the files the change produces.
- Select Review changes, check the diff, and select Add to changes. For a deletion, the review panel opens after you select Delete, and its button reads Add the deletion to changes.
- Repeat steps 2 to 4 for any other change, including changes to other resource types. Each change joins the pending changes.
- Open Pending changes. The page displays the repository, the base branch, the base path, and the signed-in user.
- If the page shows Not signed in, select Login with GitHub and authorize the GitHub App.
- Enter a Title and Description, and select Submit changes.
The Administration UI displays a link to the pull request it opened. The pull request is a draft.
Step 6: Merge the pull request
- Review the pull request on GitHub, mark it ready for review, and merge it as you do any other change.
- Wait for your GitOps tool to apply the merged commit. The new configuration appears in the Administration UI after the gateway loads it.
How changes are written
| Behavior | Details |
|---|---|
| Author | The pull request and its commits belong to the signed-in user. GitHub shows the user's name, and the commit uses the public email address of the user's GitHub account, or the GitHub no-reply address when the account keeps its email private. |
| Branch | The Administration UI pushes a branch named traefik-hub-gitops/<user>-<timestamp>. |
| Pull request state | Pull requests open as drafts. |
| Edited resources | The diff contains only the fields you changed. The rest of the file stays as it is. |
| New resources | Each new Kubernetes resource is written to a new file named <namespace>-<kind>-<name>.yaml under the root directory, for example default-ingressroute-foo.yaml. When you set TRAEFIK_HUB_DASHBOARD_GITOPS_FILEPROVIDERCONFIG, a new file provider router, service, or middleware goes into that dynamic configuration file instead of a new file. A new HTTPRoute requires a Gateway. Choose a Gateway from the manifests in your repository, or enter its name, and the Administration UI writes it to parentRefs. |
| Deleted routes | Deleting a route, such as an AI route, an MCP server, or an HTTP router, removes the router. The middlewares and services it references stay in the repository. |
| HTTP services | A service's detail page shows its Source. When a manifest in your repository produces the service, such as a TraefikService or the service entry of an IngressRoute, the page displays Edit, and the change goes to that manifest. A service that your repository doesn't define shows Not in the repository and has no Edit button. |
| Base branch changes | The Administration UI checks the base branch every 30 seconds, or at the interval you set with TRAEFIK_HUB_DASHBOARD_GITOPS_REFRESHINTERVAL, and applies your changes on top of its latest commit. |
| Credentials | Credential fields, such as the Provider credential of an AI middleware, offer Secret and Value. Secret writes a reference to a Kubernetes secret, in the form urn:k8s:secret:<name>:<key>. Value writes the text you enter into the repository as you type it. Create the Kubernetes secret yourself. |
| Sign-in | The session belongs to the browser that signed in. Signing in from another browser doesn't sign in the first one. A session lasts up to 12 hours, and the Administration UI extends it while you use it. |
Troubleshooting
The Administration UI displays "GitOps isn't enabled on this dashboard"
Error: The create, edit, and delete controls are missing, or the Pending changes page displays this message.
Cause: The Administration UI started without TRAEFIK_HUB_DASHBOARD_GITOPS_REPOSITORY.
Solution: Complete step 4 and restart the traefik-hub-admin-ui
deployment.
The Administration UI shows you as signed out after sign-in
Cause: You signed in from a different browser than the one you are using. The session cookie stays in the browser that completed the sign-in.
Solution: Select Login with GitHub in the browser where you use the Administration UI.
GitHub rejects the sign-in with a redirect error
Cause: The Callback URL of the GitHub App doesn't match <external URL>/api/gitops/callback.
Solution: Set the Callback URL in the GitHub App settings to the value of
TRAEFIK_HUB_DASHBOARD_GITOPS_EXTERNALURL followed by /api/gitops/callback.
The rollout doesn't complete after you enable GitOps
Problem: The kubectl -n traefik rollout status deploy/traefik-hub-admin-ui command doesn't finish, and the
previous pod keeps serving.
Cause: The new pod becomes ready after it fetches the repository. The fetch fails while the GitHub App isn't installed on the repository, and the Administration UI retries.
Solution: Run kubectl -n traefik logs -l app.kubernetes.io/name=traefik-hub-admin-ui --tail=20. The deployment
has two pods during the rollout, and the log of the new pod has an Unable to refresh the GitOps repository message
that gives the reason. If the reason is that the GitHub App isn't installed on the repository, open the URL in the
message, or complete step 2.
A GitOps page that answers with HTTP 503 and an install link after the Administration UI worked means the GitHub App is no longer installed on the repository. Install it again as described in step 2.
Next steps
- Administration UI configuration reference for every GitOps setting.
- Set up Analytics to monitor the traffic of the routes you change.
