Run a server
haulnet-server runs LuxonServer, an open-source Photon-compatible server, with a ready config and a small status endpoint. Keep it private and share the address, or add it to the public list.
Requirements
- Linux x86-64 (Docker or plain systemd) or Windows x64.
- A public IPv4 address (IPv6 works too); UDP not filtered by the provider. Many players have no IPv6 (in Russia about nine in ten), so an IPv6-only server is not enough.
- Bandwidth: roughly 2–4 Mbit/s outgoing per 6-player game. This is an estimate, not a measurement; an unmetered port of 100 Mbit/s or more and DDoS protection that covers UDP are recommended for public servers.
- CPU and memory are modest: LuxonServer is a single-threaded C++ program.
Ports
| Port | Protocol | Purpose | Open to players |
|---|---|---|---|
| 27000 | UDP | NameServer (players connect here first) | yes |
| 27001 | UDP | MasterServer | yes |
| 27002 | UDP | GameServer | yes |
| 27080 | TCP | Status endpoint (/status, /healthz) | yes, for server choice |
| 5088 | TCP | LuxonServer's web API, loopback only | never |
LuxonServer's own web API has no authentication and shows player addresses, user IDs and tokens. haulnet-server
always binds it to 127.0.0.1: never publish or forward port 5088.
Docker
mkdir haulnet-server && cd haulnet-server
base=https://github.com/haulnet/haulnet-server/releases/latest/download
curl -fsSLO "$base/docker-compose.yml"
curl -fsSLO "$base/haulnet-update" && chmod +x haulnet-update
curl -fsSL -o haulnet-server.env "$base/haulnet-server.env.example"
nano haulnet-server.env # set EXTERNAL_ADDRESS
docker compose up -d
docker compose logs -f
The compose file uses host networking and the image ghcr.io/haulnet/haulnet-server:latest. To stay
on one release, put HAULNET_SERVER_TAG=<version> into a file named .env next to
docker-compose.yml. Open the ports, for example with ufw:
sudo ufw allow 27000:27002/udp
sudo ufw allow 27080/tcp
Without Docker: the release also has a Linux tarball with a systemd unit (dynamic unprivileged user, read-only
system) and a Windows zip with start.bat; see the
README.
Main settings
Environment variables, or KEY=VALUE lines in haulnet-server.env:
| Variable | Default | Meaning |
|---|---|---|
EXTERNAL_ADDRESS | — (required) | Public IP or DNS name players use to reach this server. No port, no scheme. |
SERVER_NAME | haulnet-server | Name in the status endpoint and logs. |
MAX_ROOMS, MAX_PLAYERS | not set | Soft limits: Haulnet starts no new games here when reached. |
MAX_CONNECTIONS | 600 | Hard limit enforced by LuxonServer (a player uses about two: game and voice). |
STATUS_ADDRESS | :27080 | Where the status endpoint listens. |
STATS_LOG_INTERVAL | off | Log rooms, players, traffic and CPU load every
interval, e.g. 60s. |
Updating
Each release pins one LuxonServer version. When R.E.P.O. changes its Photon version, a new release follows, and Haulnet hides servers with an incompatible version, so keep the server updated.
sudo ./haulnet-update # update now if the server is empty, otherwise drain it first
sudo ./haulnet-update enable # automatic updates every 10 minutes (off by default)
sudo ./haulnet-update status
sudo ./haulnet-update rollback
While an update waits, the server drains: the status says "accepting": false, "draining": true,
Haulnet starts no new games there, and running games are not affected. If the new version does not come up within
90 seconds, the previous one starts again. Details:
Updating.
Status endpoint
curl http://<server>:27080/status
It publishes counts and versions only (rooms, players, limits, accepting, draining,
uptime), never room names, player names, addresses or IDs. Haulnet uses it to pick a server; the
server list page shows it live.
Privacy
Like any game server, yours sees the IP addresses of connecting players, and LuxonServer's log also contains player IP addresses, Steam IDs and room names. Keep logs only as long as you need them and do not publish them.
Add it to the public list
- Bring the server up and check
/statusfrom another machine. - Open a pull request to haulnet-servers with one file
servers/<region>/<city>-<N>.json, following its guide. The name, like Europe [Moscow] #1, is derived from the city and number. - CI checks the entry, its DNS and the status endpoint; a maintainer reviews and merges it. Within minutes the mod and servers.haulnet.cc show it, and the Haulnet monitor checks it once a minute.
Rules for operators are in the list's README: run the official package and keep it updated, keep the server reachable, never inspect or sell players' traffic, no ads, payments or accounts for players.
Something wrong or missing on this page? Open an issue or a pull request to haulnet.github.io.