Reforger OPS

Running an Arma Reforger server on Pterodactyl

· 5 min read

Pterodactyl is the most common hosting panel for Arma Reforger dedicated servers, self-hosted or rented. This guide covers what an admin needs to operate the server from there and, optionally, connect it to an external administration panel.

Ports: three allocations

A Reforger server uses three UDP ports, and in Pterodactyl each must be an allocation assigned to the server:

UseConventionWhere it is set
Game2001bindPort / publicPort in config.json (the primary allocation)
Steam Query (A2S)17777a2s block in config.json; this is what the server browser and status tools query
RCON19999rcon block; see how to enable RCON

If the egg only ships the game allocation, the node administrator adds the other two (Admin → Servers → Build → Allocations) and you then put them in config.json. The classic "RCON does not answer" on Pterodactyl is a port in the JSON that is not assigned to the server.

Where config.json lives

It depends on the egg. Usually the file is in the container root (/home/container/config.json) or in the profile folder (/home/container/profile/). To know for sure, look at the egg's startup variable: the start command carries -config <path>. Edit it from the Files tab; changes are read on restart.

The important secrets live there: game.passwordAdmin (the in-game #login) and rcon.password. Anyone with Files access sees them; limit Pterodactyl sub-users to what they actually need.

Restarting and stopping

Pterodactyl's Start / Restart / Stop / Kill buttons act on the process. Differences that matter:

  • Pterodactyl Restart kills the process and starts it again: it reloads config.json and mods. It takes as long as the server takes to boot (a minute or two with mods).
  • #restart over RCON restarts the match without stopping the process: it does not reload config.json. Faster, and good for "cleaning" the scenario.
  • #shutdown over RCON stops the process; on Pterodactyl with auto-restart (crash detection) it comes back on its own.

The client API

Pterodactyl has a per-user API that can do everything the interface does: read state, send power signals, read and write files. You generate a key under Account → API Credentials. The key belongs to your account, inherits your permissions and can be revoked any time. The server identifier is the 8-character short code in the URL (/server/a1b2c3d4).

With those two plus the panel URL, an external tool can restart the server, read config.json and apply changes without you opening Pterodactyl. Reforger Ops uses exactly that: restart and shutdown from the panel, validated config.json editing with a backup of the previous file (a broken JSON leaves the server unable to boot), the mod list with names and sizes from the Workshop, and one-click installation of the companion mod into the profile. The key is stored encrypted and never shown back.

Typical problems

  • The server does not show in the server browser: A2S port with no allocation, or publicAddress/publicPort pointing elsewhere.
  • Restart loop after editing config.json: invalid JSON (a stray comma). Go back to the previous copy.
  • Mods that do not load: the ID is mistyped or the mod was blocked/removed from the Workshop. Dependencies are not the problem: the server resolves and downloads them by itself, there is no need to list them in game.mods.

Where the logs actually live

When a server dies on its own, the answer is in the logs, and finding them in Pterodactyl has a catch. The server creates a new folder on every start, named logs_<date>. The most recent one belongs to the process running right now: if the server restarted, what explains the crash is in the previous folder, not the latest.

Inside each folder, three files matter: console.log (everything that happened), error.log (errors only) and crash.log if the process really died. Mind the path, too: logs hang off the folder you pass with -profile. The $profile: prefix you see in the configuration points at a subfolder of that one, so it is easy to look in the wrong place and conclude there are no logs.

console.log grows faster than you think

On a populated, modded server, console.log reaches several megabytes within a couple of hours. Pterodactyl's file viewer refuses to open files past a certain size, so precisely on the days you have something to investigate, you cannot open it. The way round it is to download the file instead of opening it in the browser, and read the end, which is where whatever happened before the crash is.

One pattern is worth gold: when a mod is broken, console.log fills with repeated lines like Failed to open or Wrong GUID carrying the mod's path. It is not one stray line: it is hundreds or thousands, and that is what separates it from the normal noise of a modded server.

Mod dependencies download themselves

You do not need to list your mods' dependencies in game.mods. The server resolves and downloads them at startup. You can see it in the server's own log: downloads appear for mods that are not in the configuration, because they are dependencies of ones that are.

This saves a lot of work with long lists, and avoids the mistake of removing a mod and leaving its dependencies stranded in the configuration. One thing to keep in mind: a mod's new version is downloaded at startup. Until the next restart, the server keeps running the old one, even when the Workshop already shows another.