BeamMP-Server on Linux is a single prebuilt binary per distribution, not a package and not something SteamCMD installs. Download the file that matches your release and CPU - BeamMP-Server.ubuntu.24.04.x86_64, BeamMP-Server.debian.12.x86_64 and so on - install the one runtime library it needs, liblua5.3-0, mark it executable and run it once. It writes a default ServerConfig.toml beside itself and stops because the auth key is empty. Paste in a key from the BeamMP Keymaster, run it again under a dedicated user through a systemd unit, open 30814 on both TCP and UDP, and the server is in the public list within a minute or two. Updating is replacing that one file.
That is the whole job, and it takes ten minutes on a fresh machine. The rest of this post is the detail that decides whether it still works after the next reboot, the next BeamNG patch and the next time somebody else has to look at it. What goes inside ServerConfig.toml - maps, MaxCars, mods, the meaning of each key - is covered in the BeamMP server guide; this post is about the Linux side of running it.
What you need before you start#
The BeamMP server is a small native C++ program. It does not simulate vehicles, it relays their state, so it is light on CPU and memory and heavy on upstream bandwidth. Any current VDS or VPS can run it; what matters is that the operating system is one the project builds for.
| Resource | Minimum | Comfortable |
|---|---|---|
| RAM | 1 GB free | 2 GB free for 10-20 players |
| CPU | 1 core | 2 cores if Lua plugins do real work |
| Disk | 100 MB plus mods | Mod pack size times two |
| Network | TCP and UDP 30814 | Good upstream, low latency |
The disk line is not a typo. The server binary is a few tens of megabytes; the Resources/Client folder holding mod zips is what grows, and keeping a copy of the last working mod set for rollback doubles it. Bandwidth is the real constraint: every vehicle update goes to every client, and every joiner downloads the whole client mod pack.
You also need:
- A supported distribution. At the time of writing the official releases are built for Debian 12, Debian 13, Ubuntu 22.04 and Ubuntu 24.04, each in
x86_64andarm64. Anything else means building from source. - sudo on the machine, to install a library, create a user and write a unit file.
- An auth key from the BeamMP Keymaster, tied to your own BeamMP account. Without one the server will not start. How to get it is in the BeamMP server guide.
If the machine is brand new, do the basics before any game server goes on it - a non-root login, SSH keys, updates. The first hour on a new VDS and SSH keys and hardening walk through both. If you are still deciding whether to run your own Linux box at all, choosing between a VDS and a game panel is the honest comparison.
Picking the right release binary#
BeamMP publishes one file per distribution, release and architecture on the BeamMP-Server GitHub releases page. As of the v3.9 releases the Linux assets are named like this:
BeamMP-Server.debian.12.x86_64BeamMP-Server.debian.12.arm64BeamMP-Server.debian.13.x86_64BeamMP-Server.debian.13.arm64BeamMP-Server.ubuntu.22.04.x86_64BeamMP-Server.ubuntu.22.04.arm64BeamMP-Server.ubuntu.24.04.x86_64BeamMP-Server.ubuntu.24.04.arm64Next to them sit matching debuginfo.* files. Those are debugging symbols for crash reports and you do not need them to run anything. BeamMP-Server.exe is the Windows build.
Two commands tell you which file is yours:
$ grep -E '^(ID|VERSION_ID)=' /etc/os-releaseID=ubuntuVERSION_ID="24.04"$ uname -mx86_64ID and VERSION_ID give the distribution and release; uname -m gives the architecture. x86_64 is ordinary Intel and AMD hardware. aarch64 is 64-bit ARM - Ampere cloud instances, a Raspberry Pi 4 or 5 on a 64-bit OS - and maps to the arm64 asset.
The binaries are built against each release's system libraries, which is why there is one per distribution rather than one for all of Linux. A mismatched file usually fails on start with a complaint about a missing or too-old GLIBC or GLIBCXX symbol. On an interim release such as Ubuntu 24.10 or 25.04 the nearest older LTS build often runs, but nobody promises it; if it fails, either move to a supported release or build from source. Fedora, Arch and Alpine are source-build territory - the README lists the build dependencies, and the ARM build needs VCPKG_FORCE_SYSTEM_BINARIES=1 exported first.
Installing the dependency and a dedicated user#
The release binary links against the system Lua 5.3 library, which minimal server images do not ship. On Debian and Ubuntu it is one package:
$ sudo apt update$ sudo apt install liblua5.3-0 ca-certificates curlca-certificates and curl are there for downloading the binary and for the server's own HTTPS calls to the BeamMP backend; both are already present on most images. If you skip the Lua library, the server dies immediately with error while loading shared libraries: liblua5.3.so.0: cannot open shared object file. Running ldd against the binary lists every library it needs and marks the missing ones not found, which is the fastest way to check before you start debugging anything else.
Next, a user that owns the server and nothing else. The BeamMP documentation itself says not to run the server as root, with sudo, or as your personal account, and the reasoning is the usual one: Lua plugins execute with the server's privileges, so a malicious or careless plugin running as root owns the machine.
$ sudo useradd --system --create-home --home-dir /opt/beammp \ --shell /usr/sbin/nologin beammpA system account with no login shell cannot be used to SSH in, and everything the server writes lands under /opt/beammp. To work in that directory as the user, use sudo -u beammp in front of commands, or sudo -u beammp -s /bin/bash for a shell.
Download and first run#
Fetch the binary straight into the server's directory. GitHub's latest/download path always resolves to the newest release, so the command below does not need a version number - change the file name for your distribution:
$ cd /opt/beammp$ sudo -u beammp curl -fL -o BeamMP-Server \ https://github.com/BeamMP/BeamMP-Server/releases/latest/download/BeamMP-Server.ubuntu.24.04.x86_64$ sudo -u beammp chmod +x BeamMP-Server$ sudo -u beammp ./BeamMP-Server --versionSaving it under the plain name BeamMP-Server rather than the long release name is deliberate. The systemd unit and any update script then point at one fixed path, and an update is a file replacement instead of an edit to the unit.
--version prints the version and exits, which proves the binary and its libraries load. The other flags the server accepts are --help, --config=/path/to/ServerConfig.toml and --working-directory=/path/to/folder. You will not need them if you run the server from its own directory, which is what the unit below does.
Now the first real run:
$ cd /opt/beammp$ sudo -u beammp ./BeamMP-ServerThe server creates its files, prints its start-up lines, and complains that the auth key is missing. Stop it with Ctrl+C if it has not exited on its own. The directory now looks like this:
/opt/beammp/ BeamMP-Server ServerConfig.toml Server.log Resources/ Client/ Server/Open ServerConfig.toml, paste your key into AuthKey, set a Name, and leave Port = 30814 unless you have a reason to change it:
$ sudo -u beammp nano /opt/beammp/ServerConfig.toml[General]Port = 30814AuthKey = "paste-your-keymaster-key-here"Name = "Linux test server"Private = trueMaxPlayers = 8MaxCars = 2Private = true while you are testing keeps the server out of the public list; you connect directly by address. Run ./BeamMP-Server once more by hand. A healthy start stays running and prints no [ERROR] lines; [WARN] lines are worth reading but rarely fatal. Ctrl+C asks the server to shut down cleanly - it fires the Lua onShutdown event and gives plugins a few seconds to finish - and pressing it repeatedly forces the exit. Once that works interactively, hand it to systemd.
The file is generated by the binary, and that matters: the keys a given version writes are the keys it reads. Copying a ServerConfig.toml from an old forum post into a new server works for [General], but sections such as [Misc] (update reminders) and the optional HTTP block vary by version. When in doubt, let the server generate a fresh file and move your values across.
A systemd service for BeamMP#
A server started in an SSH session dies with the session, and one started in tmux dies with the reboot. A unit file fixes both and puts the output in the journal. systemd services for your apps explains every directive; this is the BeamMP version:
[Unit]Description=BeamMP serverWants=network-online.targetAfter=network-online.target[Service]Type=simpleUser=beammpGroup=beammpWorkingDirectory=/opt/beammpExecStart=/opt/beammp/BeamMP-ServerKillSignal=SIGINTTimeoutStopSec=30Restart=on-failureRestartSec=10NoNewPrivileges=trueProtectSystem=fullPrivateTmp=true[Install]WantedBy=multi-user.targetThe lines that are specific to this server:
- `WorkingDirectory=/opt/beammp`. The server looks for
ServerConfig.tomland theResourcesfolder relative to where it runs. Without this line it would start in/, find no config, and try to write a new one where it has no permission. - `After=network-online.target`. The server contacts the BeamMP backend at start to validate the key. Starting before the network is up produces a confusing authentication failure on every boot.
- `KillSignal=SIGINT`. The same signal as Ctrl+C, which is the shutdown path the server documents. It lets plugins run their
onShutdownhandlers.TimeoutStopSec=30is how long systemd waits before it gives up and kills the process. - `Restart=on-failure` restarts a crash, but not a deliberate stop.
RestartSec=10stops a broken config from restarting the server in a tight loop - if the key is wrong, it fails, waits, fails again and hits systemd's start limit, which is what you want.
The three hardening lines are cheap. NoNewPrivileges stops anything the server spawns from gaining privileges, ProtectSystem=full makes /usr, /boot and /etc read-only to it, and PrivateTmp gives it its own /tmp. The server only writes inside its working directory, so none of them get in the way.
Load and start it:
$ sudo systemctl daemon-reload$ sudo systemctl enable --now beammp$ systemctl status beammpenable --now starts it immediately and at every boot. After any edit to the unit, run daemon-reload again before restarting, or systemd keeps using the old version.
One trade-off to know about: the BeamMP console accepts commands - list, kick <name> [reason], say <message>, status, lua, exit - but only in an interactive terminal. Under systemd there is no terminal attached, so day-to-day moderation goes through Lua plugins or in-game admin tools instead. If you need the console occasionally, stop the service and run the binary by hand as the beammp user. If you need it constantly, running the server inside tmux started from the unit is possible, but it brings back most of what the unit was supposed to remove; most server owners end up with a plugin instead. BeamMP Lua plugins and races shows how chat commands are built.
Opening port 30814 with ufw#
BeamMP uses one port number on two protocols: TCP for connection setup and mod downloads, UDP for vehicle state. Open only TCP and players connect, load the map and then sit there with every other car frozen, because the state stream never arrives.
If ufw is not enabled yet, allow SSH before you turn it on, or you will lock yourself out:
$ sudo ufw allow OpenSSH$ sudo ufw allow 30814/tcp comment 'BeamMP'$ sudo ufw allow 30814/udp comment 'BeamMP'$ sudo ufw enable$ sudo ufw status verboseTwo rules rather than ufw allow 30814 without a protocol, which would also work but is easier to misread later. The comment shows in ufw status and saves you guessing what a port was for six months from now. If you changed Port in the config, use the new number in both rules. The server also makes outgoing HTTPS connections to the BeamMP backend for authentication and the server list; ufw's default policy allows outgoing traffic, so there is nothing to add unless you have tightened that. The UFW firewall guide covers default policies, rule order and the Docker trap in full.
ufw is only the firewall on the machine. Many cloud providers also have a network firewall or security group in front of the instance, and it needs the same two rules. If the server answers from the machine itself but not from outside, that outer layer is the usual reason. Game server ports explained has the general picture.
To confirm the server is listening on both protocols:
$ sudo ss -tulpn | grep 30814You should see one tcp line in LISTEN state and one udp line, both owned by BeamMP-Server. If only one appears, the server is not listening on the other protocol and no firewall rule will help - check the IP setting in the config, which should be :: or 0.0.0.0 for all addresses.
Logs: journalctl and Server.log#
Logs end up in two places, and both are useful.
The journal holds everything the server prints to its console, with timestamps and service events such as crashes and restarts:
$ journalctl -u beammp -f$ journalctl -u beammp --since "1 hour ago"$ journalctl -u beammp -b -p warning-f follows live, --since narrows the window, -b limits to the current boot. The journal is also where you see systemd's view of things - "Main process exited, code=exited, status=1/FAILURE", "Start request repeated too quickly" - which the server's own log cannot tell you.
Server.log in the working directory is the server's own file. On every start the server renames the previous one to Server.old.log and begins a fresh Server.log, so you always have the current run and the one before it, and no more. If the server crashed and restarted, the evidence from before the crash is in Server.old.log. If it restarted twice, the evidence is gone. That is the main reason to rely on the journal for history: it keeps every run, rotated by size rather than by restart.
LogChat = true in the config writes chat to the log, which is the cheapest moderation evidence there is. Debug = true makes the log far more verbose; turn it on to chase a problem and off afterwards, because it grows quickly.
If the journal on a small VDS gets large, cap it in /etc/systemd/journald.conf with SystemMaxUse= and restart systemd-journald. The Linux commands for server admins post has the rest of the toolkit for reading logs - grep, tail, less - when you are digging through Server.log by hand.
Updating BeamMP-Server#
BeamMP releases follow BeamNG.drive updates, and a client on a newer protocol may refuse to join an old server. Updates are usually needed within days of a game patch, which is exactly when people want to play, so the process is worth getting smooth.
An update is: stop, back up, replace the binary, start.
$ sudo systemctl stop beammp$ cd /opt/beammp$ sudo -u beammp cp BeamMP-Server BeamMP-Server.previous$ sudo -u beammp cp ServerConfig.toml ServerConfig.toml.bak$ sudo -u beammp curl -fL -o BeamMP-Server \ https://github.com/BeamMP/BeamMP-Server/releases/latest/download/BeamMP-Server.ubuntu.24.04.x86_64$ sudo -u beammp chmod +x BeamMP-Server$ sudo -u beammp ./BeamMP-Server --version$ sudo systemctl start beammp$ journalctl -u beammp -fThe .previous copy is your rollback: if the new version misbehaves, stop the service, move the old binary back and start again. curl -f makes a failed download exit with an error rather than save a GitHub error page as your server binary, and --version before the start catches a bad file before systemd tries to run it.
Read the release notes before updating across a major version. Lua API signatures have changed between major versions before, and a plugin that worked on the old build can fail silently on the new one - the server starts, the plugin does nothing. The [Misc] section of recent configs has ImScaredOfUpdates and UpdateReminderTime keys that control the update reminder the server prints; they control the message, not the update itself. BeamMP does not update itself, and that is a good thing - you decide when a working server changes.
Resist the urge to put the download line in a cron job. An automatic update that lands mid-session, or one that pulls a release your plugins are not ready for, costs more than the two minutes the manual version takes. If the server is busy enough that update timing matters, announce a window, update, and test with a direct connect before you open it again. What to do when a mod update breaks is the general discipline.
Backups worth keeping
There is no world save in BeamMP, which makes backups small and easy to skip. What you cannot re-download is ServerConfig.toml, everything under Resources/Server (your plugins and whatever data they store) and the exact set of mod zips in Resources/Client that currently work together. A nightly tar of /opt/beammp minus the binary, copied off the machine, covers all of it. Backups that actually restore explains why off the machine is not optional.
Troubleshooting on Linux#
`error while loading shared libraries: liblua5.3.so.0`. The runtime dependency is missing. sudo apt install liblua5.3-0, then try again. On a non-Debian distribution, install that distribution's Lua 5.3 library or build from source.
`version 'GLIBC_2.xx' not found` or `GLIBCXX` errors. You downloaded the binary for a newer distribution than you are running. Check /etc/os-release and fetch the matching file.
`Exec format error`. Architecture mismatch - an arm64 binary on x86_64 or the reverse. Check uname -m.
`Permission denied` when starting. The file is not executable, or the directory is not owned by the user running it. chmod +x BeamMP-Server and sudo chown -R beammp:beammp /opt/beammp.
The service fails with "Start request repeated too quickly". The server is exiting on every start, and systemd has stopped trying. The real reason is a few lines above in journalctl -u beammp - almost always the auth key or a TOML syntax error. Fix it, then sudo systemctl reset-failed beammp and start again.
The server starts by hand but not as a service. Usually WorkingDirectory is missing or wrong, so the service cannot find the config, or files were created by root during a manual run and the beammp user cannot write them. ls -l /opt/beammp tells you which; chown fixes the second.
It runs, players cannot join. Check ss -tulpn for both protocols, then ufw status, then the provider's firewall. Test with a direct connect from outside before you suspect the server list.
Address already in use. Something else holds 30814 - often a copy you started by hand in another terminal and forgot about. ss -tulpn | grep 30814 names the process.
The server is killed with no error. On a small VDS this is often the kernel's OOM killer, usually because of something else on the machine. journalctl -k | grep -i oom confirms it. Linux swap and the OOM killer explains what to do about it.
Running it on RE:NODE#
Everything above applies to any Linux machine you control, including the i9-9900K VDS line, which is prepared by hand within 24 hours and is a sensible home if you want to run BeamMP next to other services of your own.
If you only want the BeamMP server, the BeamMP game line does the Linux part for you: the server is created when payment clears, the port is allocated on both protocols, ServerConfig.toml is edited in the browser file manager and mod packs go up over SFTP. It is one of the games that needs your own credential, so the install waits on the Setup tab until you paste your Keymaster key. At the memory limit the container is stopped and restarted clean rather than left to swap, and a server that crashes repeatedly raises a warning and a ticket. What you give up compared with a VDS is root access and the choice of distribution, which for BeamMP rarely matters.
FAQ#
Which BeamMP-Server file do I download for Ubuntu 24.04?
BeamMP-Server.ubuntu.24.04.x86_64 on ordinary Intel or AMD hardware, or BeamMP-Server.ubuntu.24.04.arm64 on ARM. uname -m tells you which; aarch64 means the arm64 file.
Does BeamMP run on Linux without Wine?
Yes. BeamMP-Server is a native Linux program with official builds for Debian and Ubuntu. Only the players need BeamNG.drive, which the server never runs.
Why does the server exit straight after the first run?
Because it has just written a default ServerConfig.toml with an empty AuthKey. Add a key from the Keymaster and start it again. If it still exits, the log line will say whether it is the key or the TOML syntax.
Can I run more than one BeamMP server on one machine?
Yes. Give each its own directory, its own Port in its config, its own auth key, its own unit file and its own pair of firewall rules. Multiple game servers on one VDS covers the layout.
Should I use the console or Lua for admin commands?
Under systemd the console is not attached to anything, so in practice Lua plugins handle kicks, bans and announcements. Keep the console for testing by hand.
Does BeamMP-Server update itself?
No. It can remind you that a newer version exists, but replacing the binary is your job. That is a stop, a download and a start, and it is worth doing by hand.


