{"id":21236112,"url":"https://github.com/auser/traefikctl","last_synced_at":"2025-06-23T16:31:52.427Z","repository":{"id":261875885,"uuid":"885601524","full_name":"auser/traefikctl","owner":"auser","description":null,"archived":false,"fork":false,"pushed_at":"2024-11-19T18:00:02.000Z","size":387,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-19T18:01:14.661Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://auser.github.io/traefikctl/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/auser.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2024-11-08T23:08:55.000Z","updated_at":"2024-11-19T18:00:06.000Z","dependencies_parsed_at":"2024-11-09T00:33:04.242Z","dependency_job_id":null,"html_url":"https://github.com/auser/traefikctl","commit_stats":null,"previous_names":["auser/traefikctl"],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/auser%2Ftraefikctl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/auser%2Ftraefikctl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/auser%2Ftraefikctl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/auser%2Ftraefikctl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/auser","download_url":"https://codeload.github.com/auser/traefikctl/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225648869,"owners_count":17502186,"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":[],"created_at":"2024-11-21T00:07:01.771Z","updated_at":"2025-06-23T16:31:52.377Z","avatar_url":"https://github.com/auser.png","language":"Rust","readme":"# Traefik Dynamic Configuration Manager\n\nA Rust library for managing Traefik dynamic configuration through etcd.\n\n## Installation\n\nHead to [https://auser.github.io/traefikctl/](https://auser.github.io/traefikctl/) for installation instructions.\n\n## Configuration\n\nThe configuration is done in the `config/config.yml` file. You can also pass in a partial etcd config via the cli to override the default config.\n\n```\ntraefikctl get -f ./config/config-devcontainer.yml --etcd-config='{\"endpoints\": [\"https://0.0.0.0:2379\"], \"tls\": {\"cert\": \"./config/tls/etcd-peer.pem\", \"key\": \"./config/tls/etcd-peer-key.pem\", \"ca\": \"./config/tls/ca.pem\", \"domain\": \"etcd\"}}'\n```\n\nThe configuration file actually contains a script using the handlebars syntax ([tera](https://docs.rs/tera/latest/tera/)) that is used to generate the configuration file, so you can use the `render` command to see what exactly is being generated before being used.\n\n```\ntraefikctl render -f ./config/config-devcontainer.yml\n```\n\nThere is a helper to use the environment variables to save typing `-f {config_file}`. Use `.envrc` to load the environment variables:\n\n```\nsource .envrc\n# Or \ndirenv allow\n```\n\n**YOU MUST RUN THE FOLLOWING COMMANDS OTHERWISE IT WILL NOT WORK:**\n\n```\ncp .devcontainer/traefik/dynamic.example.yml .devcontainer/traefik/dynamic.yml\ncp .devcontainer/traefik/traefik.example.yml .devcontainer/traefik/traefik.yml\n```\n\n## Getting Started\n\nThere are a few scripts to help you get started.\n\n```\n# Build the docker image (to contain common dependencies)\n./scripts/devex.sh build\n\n# Start the docker container\n./scripts/devex.sh start\n\n# Exec into the container\n./scripts/devex.sh exec\n```\n\n### Reset the container\n\nOccasionally you may need to reset the container. This will remove the container, rebuild the image, and start a new one. This uses the `devcontainer` command. If you do not have the `devcontainer` command, you can open vscode and run the `install devcontainer` command using the command palette.\n\n```\n./scripts/devex.sh reset\n```\n\n## Architecture\n\nThis project is built with a few goals in mind:\n\n- Keep the configuration of _traefik_ as simple as possible using etcd and a simple configuration format.\n\nTraefik is configured using a simple configuration format that is easy to understand and modify. The configuration is stored in etcd, and is automatically synced to the container. in addition, there is a frontend web app you can use to manage the configuration (more on that later).\n\n`traefikctl` is a cli tool that is used to manage the configuration. It can be executed using the `traefikctl` command or through source using `cargo run`. To see all of the commands, you can run `cargo run -- --help` or `traefikctl --help`.\n\nTo get started, you can run `traefikctl get` to see the current configuration, but you can generate your own config file using the `traefikctl generate` command.\n\n```\ntraefikctl generate -o ./config/generated.yml\n```\n\nIn the case of using the `devcontainer` command, you'll need to generate ssl certificates for the etcd server. You can use the `./scripts/gen-certs.sh` script to generate the certificates. Run the command to see all of the options.\n\nAfter you generate the certificates, you'll need to load them into the container.\n\nThe helpful script `./scripts/devex.sh` can be used to launch the devcontainer, load the certificates, run etcd, traefik, and (eventually) the frontend.\n\n### Hosts\n\nEach host has a domain, a list of paths, and a list of deployments.\n\n#### Paths\n\nEach path has a path, a list of deployments, a list of middlewares, and a boolean to strip the prefix. The deployments are keyed by the deployment name, which is used to determine which router to use.\n\n#### Deployments\n\nEach deployment has an ip, a port, a weight, and a boolean to determine if the cookie should be passed through.\n\nIt can also have a list of weights for each deployment.\n\n**The root of the project are deployments.** Every deployment will create a router in Traefik as well as a service. You can configure the deployment to handle [Traefik](https://doc.traefik.io/traefik) routes as well as `Kubernetes` routes. \n\n## Features\n\n- Strongly typed configuration using Rust structs that are automatically exported to TypeScript\n- Support for blue/green deployments with weighted load balancing\n- Middleware configuration for headers, TLS, and more\n- Host and path-based routing\n- Integration with etcd key-value store\n\n## Configuration Example\n\nThe configuration is defined in YAML format. Here's an example:\n\n```yaml\netcd:\n  endpoints: [\"https://0.0.0.0:2379\"]\n  timeout: 2000\n  keep_alive: 300\n  tls:\n    cert: \"./config/tls/etcd-peer.pem\"\n    key: \"./config/tls/etcd-peer-key.pem\"\n    ca: \"./config/tls/ca.pem\"\n    domain: herringbank.com\n\nmiddlewares:\n  enable-headers:\n    headers:\n      custom_request_headers:\n        X-Forwarded-Proto: \"https\"\n        X-Forwarded-Port: \"443\"\n        Location: \"\"\n      custom_response_headers:\n        Location: \"\"\n      access_control_allow_methods:\n        - \"GET\"\n      access_control_allow_headers:\n        - \"Content-Type\"\n      access_control_expose_headers:\n        - Location\n      add_vary_header: true\n\nhosts:\n  - domain: \"example.com\"\n    www_redirect: true\n    paths:\n      - path: \"/test\"\n        deployments:\n          blue:\n            ip: 10.0.0.1\n            port: 8080\n            weight: 50\n          green:\n            ip: 10.0.0.2\n            port: 8080\n            weight: 50\n        middlewares:  \n          - enable-headers\n          - forward-server\n\n    # Root path (catch-all)\n    deployments:\n      blue:\n        ip: 10.0.0.1\n        port: 8080\n        weight: 100\n```\n\n### Connecting to etcd\n\nYou can connect to etcd using a TLS certificate, or over an ssh tunnel. The `endpoints` field in the config file should be a list of all the etcd endpoints you want to connect to. If you are connecting over tls, you will need to provide the cert, key, and ca files. as the `tls` field.\n\n### Middleware Configuration\n\nMiddlewares are configured in the `middlewares` section. Each middleware has a name, and a set of options that are specific to the middleware. The middleware name is the name of the middleware in Traefik. The middleware name is used to apply the middleware to a path.\n\n### Host Configuration\n\nHosts are configured in the `hosts` section. Each host has a domain, a list of paths, and a list of deployments. The domain is used to determine which router to use in Traefik. The paths are used to determine which deployments to use for the path.\n\nWithout `paths`, you can configure the host to catch all paths. with a root `deployments` section. If you want to configure a specific path, you can do so with the `paths` section.\n\n### Keys in deployments\n\n- `ip` - The ip address of the deployment\n- `port` - The port of the deployment\n- `weight` - The weight of the deployment\n- `protocol` - The protocol to use to connect to the deployment. Defaults to `http` but you can set it to `tls`.\n\n## Running over an ssh tunnel\n\n```\nssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -L 2379:0.0.0.0:2379 alerner@proxy\n```\n\n## Frontend\n\nThe frontend is a simple web app that is used to manage the configuration. It is built with [Svelte](https://svelte.dev/) and [Skeleton](http://getskeleton.com/). \n\nIt is not built with any frameworks in mind, so it could be hosted on any static file server.\n\nThere is a helpful command to start the frontend  -- `cargo make dev`.\n\n\u003e If you get an error on a mac, you'll need to reinstall the `cargo-make` crate.\n\u003e Cannot run macOS (Mach-O) executable in Docker: Exec format error\n\u003e\n\u003e ```\n\u003e cargo install cargo-make --force\n\u003e cargo install cargo-watch --force\n\u003e ```\n\n## Dev notes\n\nCheck the etcd container for keys:\n\n```\n# Find the etcd container ID\ndocker ps --format '{{.ID}} {{.Image}} {{.Names}}' | awk '($2 ~ /docker.io\\/bitnami\\/etcd/ || $3 ~ /etcd$/) {print $1}'\n\n# Or as a one-liner:\nETCD_ID=$(docker ps --format '{{.ID}} {{.Image}} {{.Names}}' | awk '($3 ~ /etcd/) {print $1}')\n\n# Then use it like:\ndocker exec -it $ETCD_ID etcdctl get /traefik/config --prefix\n# Or as a one-liner:\ndocker exec -it $(docker ps --format '{{.ID}} {{.Image}} {{.Names}}' | awk '($3 ~ /etcd/) {print $1}') bash\nexport ecd=\"/opt/bitnami/etcd/bin/etcdctl --endpoints=https://localhost:2379 --cacert=/etc/etcd/tls/ca.pem --cert=/etc/etcd/tls/server.pem --key=/etc/etcd/tls/server-key.pem\"\n\n# traefik container\ndocker exec -it $(docker ps --format '{{.ID}} {{.Image}} {{.Names}}' | awk '($3 ~ /-traefik/) {print $1}') sh\n\nexport ecd=\"/bin/etcdctl --endpoints=https://etcd:2379 --cacert=/etc/traefik/tls/ca.pem --cert=/etc/traefik/tls/server.pem --key=/etc/traefik/tls/server-key.pem\"\n```\n\n## Graphviz\n\nIn case the visualization isn't helpful within yaml, you can turn it into a dot graph using graphviz\n\n```\nsudo apt update \u0026\u0026 sudo apt install graphviz\n```\n\nThen you can run the following command to generate a graph into pdf:\n\n```\ncargo run -- graph -d \u003e public/graph.dot \u0026\u0026 dot -T pdf public/graph.dot -o public/graph.pdf\n```\n\n## WINDOWS\n\nOkay, to get this working on windows, you'll need to make sure [Docker Desktop](https://docs.docker.com/desktop/install/windows-install/) is installed and running _and_ connected to the WSL 2 backend. You'll also need to make sure you have the `devcontainer` command installed. You can install it using VSCode.\n\nPress `Ctrl+Shift+P` and search for `install devcontainer` and run the command.\n\nThis does **not** work with powershell, you must use [wsl](https://docs.microsoft.com/en-us/windows/wsl/install) to run the commands.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fauser%2Ftraefikctl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fauser%2Ftraefikctl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fauser%2Ftraefikctl/lists"}