What the server process needs
BeamMP-Server is a small C++ program that relays vehicle and player state between BeamNG.drive clients running the BeamMP mod. It does no physics and needs no GPU. The README of the BeamMP/BeamMP-Server repository gives minimum figures it calls guesstimated and subject to change with each release:
| Resource | README minimum | What moves it up |
|---|---|---|
| Memory | 50+ MiB usable, OS not counted | Lua plugins, player count |
| CPU | more than 1 GHz, preferably multicore | players, cars per player |
| Disk | 10 MiB plus mods and plugins | map and vehicle zips in Resources/Client |
| Upload | 5-10 Mb/s | players, and mod downloads on join |
| GPU | none | nothing |
The upload line is the one to watch. Every zip in Resources/Client is downloaded by each player who joins, per the installation guide, so a modded map is pushed to every new client from your port. That traffic is the server's real cost, not CPU.
Ports, protocol and the AuthKey
- Port:
Port = 30814by default, any value from 1024 to 65535. The source (TNetwork.cpp) opens a TCP listener and a UDP socket on the same number, and the installation guide asks for both to be allowed through the firewall. - IPv4 only. The installation guide says the server supports IPv4 and that IPv6 support is planned. Players connect to your IPv4 address.
- AuthKey: created at keymaster.beammp.com after a Discord login. A public server needs it to appear in the server list, and the docs recommend it on private servers too. Each account has a limited number of keys, and one key runs one server at a time.
- Private:
Private = true(the default) keeps the server off the list; anyone with the IP and port can still connect. Set it tofalseto be listed.
The docs say to treat the key like a password. The steps below write it into a file only the service user can read and pass it through standard input, so it never appears in ps output or shell history.
Choosing the machine
By the README's numbers almost any whole machine is oversized for the CPU side, so choose on city and port. Pick the city nearest your players from the five data centres; all of them sit on our own network, AS19624. Every server includes an unmetered port, 1 Gbps on most lines and 500 Mbps on the rest, so mod downloads on join are not a transfer bill. The game server hosting page describes the platform and links the configurations; delivery takes about 30 minutes for a server already racked, counted from approval of the order, and 4-24 hours for a build to order.
- x86_64 lines running Ubuntu 22.04 or 24.04: the target of this page. Ubuntu installs in one click on the Linux servers.
- Out-of-band console: rack servers and blades carry one (HPE iLO, Dell iDRAC or a Supermicro BMC). Among the Moonshot cartridges only the m510 and m710x have a console; the others have power control only.
- Not the X-Gene ARM cartridge. BeamMP does ship arm64 builds, but only for Ubuntu 22.04/24.04 and Debian 12/13, and that cartridge installs Ubuntu 16.04 and 18.04 and nothing else.
Installing BeamMP-Server on Ubuntu 24.04
Run as root (sudo -i). The block installs the runtime library named in the README, creates a beammp system user (the docs advise against running the server as root or as your own account), turns on ufw with SSH allowed before any game port, then downloads the v3.9.3 asset and installs it only if its SHA-256 matches the digest GitHub lists for that file. It refuses to replace an existing binary; updates are covered further down.
apt-get update && apt-get install -y liblua5.3-0 curl ufw
id beammp >/dev/null 2>&1 || useradd --system --create-home --home-dir /opt/beammp --shell /usr/sbin/nologin beammp
sed -i 's/^IPV6=.*/IPV6=yes/' /etc/default/ufw
ufw allow OpenSSH && ufw --force enable && ufw allow 30814/tcp && ufw allow 30814/udp
V=v3.9.3; F=BeamMP-Server.ubuntu.24.04.x86_64
cd /opt/beammp && if [ -e BeamMP-Server ]; then echo "binary exists, use the update steps"; else
curl -fL -o BeamMP-Server.new "https://github.com/BeamMP/BeamMP-Server/releases/download/$V/$F" &&
echo "7de765ccbb9c2ae685c5394c70518a1a948801fb488ea419150fb54f5b41bd0b BeamMP-Server.new" | sha256sum -c - &&
install -m 755 BeamMP-Server.new BeamMP-Server && rm BeamMP-Server.new && ./BeamMP-Server --version
fi
The digest is for BeamMP-Server.ubuntu.24.04.x86_64 in v3.9.3. On 22.04 or arm64, set F to that asset's name and paste the digest shown beside it on the release page. Newer tags may be marked pre-release on GitHub; v3.9.3 was the latest stable release when this was written.
ServerConfig.toml, the key and the systemd unit
The docs generate the config by starting the server once. Writing it yourself avoids a first start with no key and lets the file be created at mode 600 before anything secret goes in. Still as root: the block writes the config and the unit only if neither exists, then the last line asks for the key without echoing it, checks its 36-character format and writes it through sed -f - as the beammp user. The service starts only when the file then holds a key of the right shape; otherwise the line says why it stopped.
cd /opt/beammp && if [ -e ServerConfig.toml ] || [ -e /etc/systemd/system/beammp.service ]; then echo "config or unit exists, not overwriting"; else
install -m 600 -o beammp -g beammp /dev/null ServerConfig.toml && cat > ServerConfig.toml <<'EOF'
[General]
Name = "My BeamMP Server"
Description = "Freeroam"
Tags = "Freeroam"
Port = 30814
IP = "::"
Private = true
AllowGuests = false
MaxPlayers = 8
MaxCars = 1
Map = "/levels/gridmap_v2/info.json"
ResourceFolder = "Resources"
LogChat = false
Debug = false
InformationPacket = true
AuthKey = ""
[Misc]
ImScaredOfUpdates = false
UpdateReminderTime = "30s"
EOF
cat > /etc/systemd/system/beammp.service <<'EOF'
[Unit]
Description=BeamMP-Server
Wants=network-online.target
After=network-online.target
[Service]
User=beammp
Group=beammp
WorkingDirectory=/opt/beammp
ExecStart=/opt/beammp/BeamMP-Server
UMask=0077
Restart=always
RestartSec=10
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload; fi
read -rs -p 'AuthKey: ' K; echo; [[ $K =~ ^[A-Za-z0-9-]{36}$ ]] && printf 's|^AuthKey = .*|AuthKey = "%s"|\n' "$K" | sudo -u beammp sed -i -f - /opt/beammp/ServerConfig.toml; unset K; if grep -Eq '^AuthKey = "[A-Za-z0-9-]{36}"$' /opt/beammp/ServerConfig.toml; then systemctl enable --now beammp && echo started; else echo "no valid AuthKey in ServerConfig.toml: service not started, re-run this last line"; fi
journalctl -u beammp -f shows the log; the docs say a healthy start has no [ERROR] lines. Two things from the source are worth knowing. TConfig.cpp rewrites ServerConfig.toml from the loaded values on every start, so comments you add are dropped; the file keeps its mode, and UMask=0077 covers the case where it has to be created. TConfig.cpp also warns when the key is not 36 characters long. Change MaxPlayers, MaxCars, Map, Name, Tags and Private with sudo -u beammp nano /opt/beammp/ServerConfig.toml, then systemctl restart beammp.
Mods, maps and Lua plugins
- Vehicle mods: drop the zip into
/opt/beammp/Resources/Client. Clients download it when they join. - Stock maps: set
Mapto one of the documented paths, for example/levels/west_coast_usa/info.json,/levels/utah/info.jsonor/levels/italy/info.json. Nothing to install. - Modded maps: put the zip in
Resources/Client, read the folder name inside itslevelsdirectory without extracting it, and setMap = '/levels/FOLDER/info.json'. - Server plugins: the README says the server runs Lua mods. TLuaEngine.cpp loads each folder inside
Resources/Serveras its own plugin state. - Protected mods: the console command
protectmod FILE.zip truestops a mod from being sent; players must obtain the file themselves.
Files you add must be owned by beammp: chown -R beammp:beammp /opt/beammp/Resources. The docs warn that a join that stalls at a done or start message usually means a broken or incompatible mod; remove mods until it stops.
Console, logs and a clean stop
The console help (TConsole.cpp) lists help, exit, kick, list, say, lua, settings, status, clear, version, protectmod and reloadmods. Under systemd there is no terminal to type into: with no TTY the bundled commandline library (commandline.cpp picks BufferedBackend.cpp when there is no terminal) only reads standard input, which systemd leaves empty. For console work, run systemctl stop beammp, then sudo -u beammp bash -c 'cd /opt/beammp && ./BeamMP-Server', type your commands, leave with exit, and start the service again. Do not run both at once; a key serves one server at a time.
SignalHandling.cpp treats SIGTERM and SIGINT as a graceful shutdown, so systemctl stop (SIGTERM by default) kicks players with a shutdown message and gives plugins their onShutdown event (main.cpp waits up to 5 seconds for it). The log also goes to Server.log in the working directory; the docs say it never shows the AuthKey.
Backups, restores and updates
What has to survive is ServerConfig.toml and Resources (mods, Client/mods.json, which TResourceManager.cpp uses for protected-mod state, and plugins with any data they keep). The binary comes from GitHub again. As root: install -d -m 700 /root/beammp-backups && umask 077 && f=/root/beammp-backups/beammp-$(date +%F-%H%M).tar.gz && tar -czf "$f" -C /opt/beammp ServerConfig.toml Resources && tar -tzf "$f" >/dev/null && echo "ok $f". If a plugin writes files while running, stop the service for the copy. The archive holds the key: copy it off the machine yourself and keep that copy private.
- Restore as root (
sudo -i). Every command below names the archive by its full path; replaceBACKUPwith the file's name in/root/beammp-backups. systemctl stop beammp.- Set the current state aside and swap the backup in, as one command, so nothing is deleted unless a fresh copy was made in this same run and both archives verify: `if [ -e /root/beammp-previous.tar.gz ]; then echo "remove or move /root/beammp-previous.tar.gz first, nothing changed"; else tar -czf /root/beammp-previous.tar.gz -C /opt/beammp ServerConfig.toml Resources && tar -tzf /root/beammp-previous.tar.gz >/dev/null && tar -tzf /root/beammp-backups/BACKUP.tar.gz >/dev/null && rm -rf /opt/beammp/Resources && tar -xzf /root/beammp-backups/BACKUP.tar.gz -C /opt/beammp && chown -R beammp:beammp /opt/beammp/ServerConfig.toml /opt/beammp/Resources && chmod 600 /opt/beammp/ServerConfig.toml && echo restored || echo "restore stopped: read the error above"; fi`.
systemctl start beammpand read the log.- Rolling back means unpacking the set-aside copy, not making a new one: `systemctl stop beammp; tar -tzf /root/beammp-previous.tar.gz >/dev/null && rm -rf /opt/beammp/Resources && tar -xzf /root/beammp-previous.tar.gz -C /opt/beammp && chown -R beammp:beammp /opt/beammp/ServerConfig.toml /opt/beammp/Resources && chmod 600 /opt/beammp/ServerConfig.toml && systemctl start beammp`.
- Once the server runs as you want, delete
/root/beammp-previous.tar.gz. The next restore refuses at step 3 while that file exists.
The maintenance page describes an update as replacing the old executable with the new one. The block below is self-contained, run as root: set V, F and D to the new tag, the asset for your release and the SHA-256 GitHub lists beside it. Nothing is stopped until the download matches that digest, and it refuses while an older BeamMP-Server.previous is still in place.
V=v3.9.3; F=BeamMP-Server.ubuntu.24.04.x86_64; D=7de765ccbb9c2ae685c5394c70518a1a948801fb488ea419150fb54f5b41bd0b
cd /opt/beammp && if [ -e BeamMP-Server.previous ]; then echo "remove or move BeamMP-Server.previous first"; else
curl -fL -o BeamMP-Server.new "https://github.com/BeamMP/BeamMP-Server/releases/download/$V/$F" &&
echo "$D BeamMP-Server.new" | sha256sum -c - &&
systemctl stop beammp && mv BeamMP-Server BeamMP-Server.previous &&
install -m 755 BeamMP-Server.new BeamMP-Server && rm BeamMP-Server.new &&
systemctl start beammp && echo updated || echo "update stopped: read the error above"
fi
To go back to the old binary: systemctl stop beammp; cd /opt/beammp && mv BeamMP-Server.previous BeamMP-Server && systemctl start beammp. When the new version has run cleanly, delete /opt/beammp/BeamMP-Server.previous; the next update stops while that name is taken.
Licence and where this setup stops
The repository's LICENSE file is the GNU Affero General Public License v3. Our general reading, not legal advice: running the unmodified release for your own players owes nothing. Distributing copies, modified or not, means passing on the corresponding source under the same licence, and a modified build that players use over the network must offer them its source. The README adds the project's own rule that only unmodified, original source may be built for public use, and that builds should come from a tag, not master.
Limits: players need IPv4; the server list and keys depend on the BeamMP backend; and a partner host's panel is a different flow, since the VPS guide says ServerConfig.toml is locked there. On your own machine you hold root and edit everything.
Questions
Which ports does a BeamMP server use?
One port number, 30814 unless you change Port, on both TCP and UDP. The docs tell you to allow both directions through the firewall. A server in our racks has no home router in front of it to forward ports, so the ufw rules above are the whole job.
Do I need an AuthKey for a private server?
A private server works without the list, and anyone with the IP and port can join it. The docs still recommend a key on private servers. A public server must have one to appear in the server list.
Can I run two BeamMP servers on one machine?
Yes, as long as each has its own directory, its own ServerConfig.toml, its own unit and a different port, and each has its own AuthKey: the docs say one key runs one server at a time. Allow the second port in ufw for TCP and UDP.
Does it run on Windows?
BeamMP ships BeamMP-Server.exe, and the release notes say it needs the Visual C++ Redistributables. On our lines Windows Server is a licence billed on top of the machine, which is one reason this page uses Linux.
How many players can one server take?
MaxPlayers sets the cap and MaxCars the cars each player may spawn; the docs put no hard ceiling on either. Our reading: the README's minimum is far below any whole machine, so upload bandwidth and the size of the mods you serve are the likelier limit.