{"id":26633122,"url":"https://github.com/bra1l0r/hopper-rs","last_synced_at":"2025-08-18T16:05:44.214Z","repository":{"id":38683188,"uuid":"505227989","full_name":"BRA1L0R/hopper-rs","owner":"BRA1L0R","description":"Hopper - Fast, configurable, lightweight Reverse Proxy for Minecraft","archived":false,"fork":false,"pushed_at":"2023-07-29T23:02:46.000Z","size":327,"stargazers_count":198,"open_issues_count":1,"forks_count":11,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-26T15:41:35.766Z","etag":null,"topics":["bungeecord","minecraft","minecraft-server","proxy","reverse-proxy","rust","velocity"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BRA1L0R.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-06-19T21:58:35.000Z","updated_at":"2025-04-17T05:07:12.000Z","dependencies_parsed_at":"2024-01-15T15:47:56.020Z","dependency_job_id":"554bf273-cad1-4675-9684-636137680558","html_url":"https://github.com/BRA1L0R/hopper-rs","commit_stats":null,"previous_names":[],"tags_count":56,"template":false,"template_full_name":null,"purl":"pkg:github/BRA1L0R/hopper-rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BRA1L0R%2Fhopper-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BRA1L0R%2Fhopper-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BRA1L0R%2Fhopper-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BRA1L0R%2Fhopper-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BRA1L0R","download_url":"https://codeload.github.com/BRA1L0R/hopper-rs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BRA1L0R%2Fhopper-rs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271019402,"owners_count":24685678,"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","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["bungeecord","minecraft","minecraft-server","proxy","reverse-proxy","rust","velocity"],"created_at":"2025-03-24T15:13:46.446Z","updated_at":"2025-08-18T16:05:44.176Z","avatar_url":"https://github.com/BRA1L0R.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hopper ![License](https://img.shields.io/github/license/BRA1L0R/hopper-rs?style=flat-square)\n\n\u003cimg src=\"./.github/hopper.webp\" align=\"right\" width=\"180\"\u003e\n\n**Hopper** is a lightweight reverse proxy for minecraft. It allows you to connect multiple servers under the same IP and port, with additional functionalities, just like **Nginx**. It is built with **Rust 🦀** to ensure maximum performance and efficiency.\n\nHopper works starting from version **1.7** up to the **latest** version of Minecraft.\n\nNOTE: this proxy is still heavily under development, and a lot of new features are coming really soon!\n\n**FEATURES:**\n\n- [x] Load balancing\n- [x] [Hot reload](#hot-reload)\n- [x] [IP Forwarding](#ip-forwarding)\n- [x] [HAProxy v2 (PROXY protocol)](#proxy-protocol-aka-haproxy-v2)\n- [x] [RealIP](#realip) 2.4 support\n- [x] [Logging metrics](#logging-metrics-with-influxdb) with InfluxDB\n- [x] Forge support\n- [ ] Webhook callbacks for events\n- [ ] Plugin system for Docker and hosting provider integrations\n\n## Index\n- [Configuration](#configuration)\n  - [Load balancing](#load-balancing)\n  - [IP Forwarding](#ip-forwarding)\n    - [Bungeecord](#bungeecord)\n    - [RealIP](#realip)\n    - [PROXY Protocol](#proxy-protocol-aka-haproxy-v2) (HAProxy)\n  - [Metrics](#logging-metrics-with-influxdb)\n- [Building and running](#how-to-run)\n  - [Docker](#docker-github-workflow-status)\n    - [docker-compose configuration](#using-docker-compose-recommended)\n  - [Binary](#binary-github-workflow-status)\n    - [Systemd service configuration](#systemd-configuration)\n- [Log verbosity](#changing-the-verbosity-level)\n- [Hot reload](#hot-reload)\n\n## Configuration\n\nTo **quickly** get started checkout this example configuration:\n\n\u003cdetails\u003e\n\u003csummary\u003eExample \u003ccode\u003eConfig.toml\u003c/code\u003e:\u003c/summary\u003e\n\n```toml\n# the address hopper will listen on\nlisten = \"0.0.0.0:25565\"\n\n# metrics configuration\n# [metrics]\n# type = \"influx\"\n# ...\n#\n# follow the section below for more information about\n# gathering metrics with hopper\n\n# general routing configuration\n[routing]\ndefault = { ip = \"127.0.0.1:12345\" } # optional\n# default = { ip = [\"127.0.0.1:12001\", \"127.0.0.1:12002\"] } # load balanced\n\n# list of servers fronted by hopper\n[routing.routes]\n# simple reverse proxy\n\"mc.gaming.tk\" = { ip = \"docker_hostname:25008\" } # hostnames are supported too!\n\n# bungeecord's ip forwarding feature enabled\n\"mc.server.com\" = { ip-forwarding = \"bungeecord\", ip = \"127.0.0.1:25123\" }\n\n# RealIP ip forwarding feature enabled\n\"mc.withrealip.com\" = { ip-forwarding = \"realip\", ip = \"127.0.0.1:26161\" }\n\n# this will load balance between the two servers\n\"other.gaming.tk\" = { ip = [\"127.0.0.1:25009\", \"10.1.0.1:25123\"] }\n```\n\u003c/details\u003e\n\u003cbr/\u003e\n\n### Load balancing\n\nHopper's load balancer is a hash distributor based on the player's source IP and port.\n\nYou can load balance players between two backend servers by specifying a **list**\nof ip addresses instead of a single address.\n\n\n```toml\n[routing]\ndefault = { ip = [\"1.1.1.1:25565\", \"2.2.2.2:25577\"] } # works on non-default routes too\n```\n\n### IP Forwarding\n\nWithout IP Forwarding, when servers receive connections from this reverse proxy they won't see the original client's ip address. This may lead to problems with sessions with plugins such as AuthMe. Hopper implements both the legacy BungeeCord protocol and the more versatile RealIP one.\n\n#### Bungeecord\n\nYou must enable bungeecord ip-forwarding inside of `spigot.yml` just like you would using bungeecord. [Click here](https://shockbyte.com/billing/knowledgebase/38/IP-Forwarding-in-BungeeCord.html) to learn more.\n\nYou can enable ip forwarding **per-server** on hopper with the \"ip-forwarding\" directive:\n\n```toml\n# You can either do it this way\n[routing.routes]\n\"your.hostname.com\" = { ip-forwarding = \"bungeecord\", ip = \"\u003cyour server ip\u003e\" }\n\n# or this way\n[routing.routes.\"your.hostname.com\"]\nip-forwarding = \"bungeecord\" # available options are: bungeecord, none. Defaults to none\nip = \"\u003cyour server ip\u003e\"\n```\n\n#### RealIP\n\nHopper supports up to RealIP v2.4 (private/public key authentication has been implemented for versions after that, which only works with TCPShield).\n\n⚠️ Note: RealIP v2.4 was built using older dependencies, hence support for newer minecraft versions may be lacking.\n\nYou must whitelist Hopper's ip address (or network) by adding a line inside of `plugins/TCPShield/ip-whitelist/tcpshield-ips.list`.\n\nFinally, you must enable RealIP support in your `Config.toml`:\n\n```toml\n[routing.routes]\n\"your.hostname.com\" = { ip-forwarding = \"realip\", ip = \"\u003cyour server ip\u003e\" }\n```\n\n#### PROXY Protocol a.k.a HAProxy V2\n\nSupport for [PROXY Protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) is available by setting `ip-forwarding` to `proxy_protocol`. Only the 2nd version of\nthe protocol (the one supported by Bungeecord out of the box) is implemented in Hopper.\n\nExample configuration:\n\n```toml\n[routing.routes]\n\"my.bungee.hostname.com\" = { ip-forwarding = \"proxy_protocol\", ip = \"\u003cyour server ip\u003e\" }\n```\n\n### Logging metrics with InfluxDB\n\nHopper supports **cheap** (resource-wise), easily configurable data gathering through the help of an external database like InfluxDB (although other databases will be supported in the future, I still recommend InfluxDB whose query language is very easy and versatile).\n\nYou must first configure an InfluxDB instance and get a **token** with writing privilege before moving along with this section.\n\nAdd and modify this configuration section in `Config.toml` according to your setup:\n\n```toml\n[metrics] # top-level section\ntype = \"influxdb\"\n# hostname = \"my-hostname\" # OPTIONAL, defaults to system hostname\nurl = \"\u003chttp/https\u003e://\u003cinfluxdb-host-or-ip\u003e:\u003cport\u003e/\"\norganization = \"\u003cYour organization\u003e\"\nbucket = \"\u003cYour data bucket\u003e\"\ntoken = \"\u003cYour access token\u003e\"\n```\n\nHopper will start logging every **5 seconds** according to this data format:\n\n**Measurement \"traffic\":**\n| Field | Type | Description |\n| ----- | ---- | ----------- |\n| host | Tag | system (or custom if specified) hostname generating this metric |\n| destination_hostname | Tag | the hostname clients connected corresponding to these metrics |\n| clientbound_traffic | Value (int) | the traffic this host generated server=\u003eclient |\n| serverbound_traffic | Value (int) | same as above, but client=\u003eserver |\n| open_connections | Value(int) | connections opened in the moment of the measurement |\n| total_game | Value(int) | people who attemped or succeded joining this server |\n| total_ping | Value(int) | people who pinged this server |\n\n_NOTE: Since counters reset through restarts, data manipulation using the influx query language allows you to aggregate rows and get persistent results._\n\n## How to run\n\nThere are two ways to run hopper:\n\n- Using the [docker image](#docker-)\n- Using the [binaries](#binary-)\n\n### Docker ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bra1l0r/hopper-rs/docker.yml?label=Container%20Build\u0026style=flat-square)\n\n- Pull the latest image from the GitHub registry:\n\n```sh\ndocker pull ghcr.io/bra1l0r/hopper-rs\n```\n\n- Create a `Config.toml` (NOTE: the port you will specify must match the exposed port below)\n- Run it using docker:\n\n```sh\ndocker run -d -p 25565:25565 -v /home/user/path-to/Config.toml:/Config.toml ghcr.io/bra1l0r/hopper-rs\n```\n\n#### Using docker-compose **(recommended)**:\n\n```yaml\n# new versions of compose don't require this anymore\nversion: \"3\"\n\nservices:\n  hopper:\n    image: ghcr.io/bra1l0r/hopper-rs\n    ports:\n      - 25565:25565\n    volumes:\n      - ./Config.toml:/Config.toml\n```\n\n### Binary ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bra1l0r/hopper-rs/build.yml?label=Artifact%20Release\u0026style=flat-square)\n\nYou can either download the [latest release](https://github.com/BRA1L0R/hopper-rs/releases) **(recommended)** or follow the steps below to build your own binary:\n\n- Download and install the latest version of the rustc toolchain\n- Clone and build the repo:\n\n```sh\n# Clone the repo into hopper-rs and enter the directory\ngit clone https://github.com/BRA1L0R/hopper-rs\ncd hopper-rs/\n\n# Build the project with the release profile\ncargo build --release\n```\n\n- The runnable binary will now be available at `target/release/hopper`\n\n#### Systemd configuration\n\nAssuming both the `hopper` binary and `Config.toml` configuration file\nare located inside `/opt/hopper`, you can extend this systemd configuration\nthat supports both the `stop` and `reload` commands.\n\nIt is **strongly** advised not to use the root user as a best practice,\nhowever this configuration does use it and is to be intended as a **template**.\n\n```\n[Unit]\nDescription=Hopper reverse proxy\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=/opt/hopper/hopper\nExecReload=/bin/kill -HUP $MAINPID\nExecStop=/bin/kill -SIGINT $MAINPID\nWorkingDirectory=/opt/hopper\n\n[Install]\nWantedBy=multi-user.target\n```\n\n## Changing the verbosity level\n\nIf you think something is off with your instance and want to enable debug logging, or you just want to reduce the default talkativeness of hopper you must choose your desired level of verbosity through the `RUST_LOG` environment variable.\n\n| Level | Description                                                                     |\n| ----- | ------------------------------------------------------------------------------- |\n| off   | No console output at all                                                        |\n| error | Only output important errors such as an unreachable backend server              |\n| info  | Informative data such as incoming connections and the current listening address |\n| debug | More descriptive errors (includes failed handshakes and bad packet data)        |\n\n_Default: `info`_\n\nExample:\n\n```sh\nRUST_LOG=\"debug\" ./hopper\n```\n\n## Hot reload\n\nHot reloading of Config.toml is supported only on linux as it provides the best way\nto signal the process to perform a hot reload.\n\nIf you think you know how something similar might be implemented in Windows\nplease [open an issue](https://github.com/BRA1L0R/hopper-rs/issues) explaining\nyour idea.\n\nHopper supports hot reloading through the `SIGHUP` process signal. Just like\nnginx. A rudimentary example of doing this would be through the `kill` command:\n\n```\nkill -s sighup \u003cprocess PID\u003e\n```\n\nIf the new configuration contains the reload is **aborted** and the server **continues\nrunning** with the previous configuration.\n\nYou can automate this with systemd, allowing for the handy `systemctl reload \u003cservice\u003e` shortcut,\nas you can see explained [here](#systemd-configuration).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbra1l0r%2Fhopper-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbra1l0r%2Fhopper-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbra1l0r%2Fhopper-rs/lists"}