Field-tested TGC deployment: this layout separates the SPT/Fika backend from one or more dedicated headless raid hosts. It was validated with a playable client joining and completing a raid hosted by a separate headless instance.

What this deployment builds

The finished stack uses independent Pterodactyl servers for each responsibility:

  • SPT/Fika Backend — accounts, profiles, configuration, matchmaking, and the Fika server mod.

  • Fika Headless 01 — a Wine-based Escape from Tarkov client dedicated to hosting raids.

  • Fika Headless 02+ — optional additional raid hosts, each with its own profile and UDP allocation.

  • Player clients — normal Windows SPT/Fika installations that connect to the backend.

Keeping these roles separate makes failures easier to diagnose and allows additional headless capacity without rebuilding the backend.

Known-good version lock

This guide documents the exact combination tested by TGC. Treat it as a version-locked stack:

  • SPT 4.1.5-40743-7d7add5

  • Fika Server 2.4.0

  • Fika Headless Manager and plugin 1.5.1

  • .NET 10 for the backend and headless manager

  • Backend image: ghcr.io/pelican-eggs/yolks:dotnet_10

  • Headless image: ghcr.io/pelican-eggs/yolks:wine_latest

Do not mix SPT, Fika, plugin, or client versions. A headless client is still a game client and must match the backend and playable clients.

Before you begin

  • A working Pterodactyl panel and Wings node.

  • A legitimate Escape from Tarkov installation.

  • A locally tested Windows SPT/Fika client matching the versions above.

  • Enough storage for every complete headless client copy.

  • One unique UDP allocation and one unique profile for every headless instance.

Do not redistribute Battlestate Games files. Build each HardCopy from files you are legally entitled to use, and follow the current SPT and Fika project rules.

1. Import the two Pterodactyl eggs

Import the version-locked backend egg and the HardCopy headless egg through the Pterodactyl administration panel:

egg-spt-4.1.5-fika-2.4-backend.json
egg-spt-fika-headless-hardcopy-v6.json

Create the backend first. Create headless servers only after the backend starts successfully.

2. Create the SPT/Fika backend

Allocations

  • 6969/TCP — SPT HTTP/API traffic.

  • 6790/UDP — Fika backend traffic when required by your configuration.

Core variables

INSTALL_FIKA=true
LISTEN_ALL_NETWORKS=true
BACKEND_IP=YOUR_PUBLIC_IP
BACKUPS_ENABLED=true

BACKEND_IP is a bare address. Do not enter https:// and do not append :6969. The egg binds the service to 0.0.0.0 while advertising the supplied address.

The backend lives at:

/home/container/SPT

Start it and wait for SPT.Server.Linux to finish loading. Confirm that the Fika server plugin is listed before continuing.

3. Prepare the Windows HardCopy

  1. Build and test a normal Windows SPT 4.1.5 client.

  2. Install the matching Fika client plugin.

  3. Confirm that the client reaches the backend and can enter the menu.

  4. Close the launcher and game cleanly.

  5. Upload the contents of that working client into the headless server's Headless directory.

The executable must land at this exact path:

/home/container/Headless/EscapeFromTarkov.exe

A common upload mistake creates /home/container/Headless/Headless/EscapeFromTarkov.exe. Move the inner contents up one level if that happens.

4. Create Headless 01

Suggested resources

  • Memory: 32 GiB

  • CPU: up to 800% on an eight-thread allocation

  • Disk: 120–150 GiB

  • Network: one unique UDP allocation, beginning with 25565

Core variables

PROFILE_ID=UNIQUE_HEADLESS_PROFILE_ID
BACKEND_URL=https://BACKEND_CONTAINER_IP:6969
PUBLIC_IP=YOUR_PUBLIC_IP
SERVER_PORT=25565
HEADLESS_TITLE=TGC Headless 01
DISPLAY_DEPTH=24
RESTART_DELAY=10
FAULT_GRACE_PERIOD=5
EXTRA_LOGGING=true

BACKEND_URL is different from the backend's BACKEND_IP. It is a complete URL used by the headless container to reach the backend. On the same Wings node, the backend container's Docker address avoids external NAT or hairpin-routing problems.

Use the Pterodactyl server UUID to inspect the backend container address from the Wings host:

sudo docker inspect \
  -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \
  BACKEND_SERVER_UUID

Docker addresses can change if networking is recreated. If every headless client suddenly loses the backend, re-check this address first.

5. Give every headless client a unique identity

Each headless host needs its own backend profile JSON. Never reuse a player profile or another headless profile.

From the Wings host, list backend profiles with:

sudo find \
  /var/lib/pterodactyl/volumes/BACKEND_VOLUME_UUID/SPT/user/profiles \
  -maxdepth 1 -type f -name '*.json' -printf '%f\n'

The PROFILE_ID value is the JSON filename without .json. For example:

Profile file:  abc123def456.json
PROFILE_ID:   abc123def456

When cloning a configured headless server, clear the copied PROFILE_ID before its first start, then assign the new identity. Reusing the original value makes two hosts compete for the same backend profile.

6. Understand the generated startup manager

The v6 egg starts through:

bash /home/container/startup.sh

Its generated watchdog performs the repetitive work automatically:

  • Runs FikaHeadlessManager --prepare.

  • Creates and reuses a persistent Wine prefix.

  • Starts a virtual display at 1024x768x24.

  • Applies WINEDLLOVERRIDES="winhttp=n,b".

  • Launches Tarkov with -nographics -batchmode.

  • Passes the unique profile token, backend address, title, public address, and raid port.

  • Tails BepInEx/LogOutput.log into the Pterodactyl console.

  • Detects Wine page faults, terminates the failed process, and restarts after the configured delay.

The important display line should resolve to:

Xvfb :0 -screen 0 1024x768x24

A depth of 16 caused the tested client to fail. Keep DISPLAY_DEPTH=24.

7. Start and validate Headless 01

  1. Start the SPT/Fika backend and leave it running.

  2. Start Headless 01.

  3. Watch for the headless manager preparation step.

  4. Confirm the virtual display uses 24-bit color.

  5. Confirm BepInEx loads Fika without a version error.

  6. Confirm the backend recognizes the headless profile.

  7. Launch a playable client, create a raid, and select the headless host.

  8. Enter and complete a short raid before scaling the deployment.

The headless game process may exit when a raid ends. The watchdog restarting it after roughly ten seconds is expected behavior.

8. Add Headless 02 and later instances

The cleanest repeatable method is to create another server from the same headless egg, assign a new UDP port, and copy only the verified HardCopy.

On the Wings host:

SOURCE_VOLUME=/var/lib/pterodactyl/volumes/SOURCE_SERVER_UUID
TARGET_VOLUME=/var/lib/pterodactyl/volumes/TARGET_SERVER_UUID

sudo rsync -aH --info=progress2 \
  --exclude='BepInEx/LogOutput.log' \
  --exclude='Headless.log' \
  "$SOURCE_VOLUME/Headless/" \
  "$TARGET_VOLUME/Headless/"

sudo chown -R \
  --reference="$TARGET_VOLUME" \
  "$TARGET_VOLUME/Headless"

Then configure the new instance:

PROFILE_ID=SECOND_UNIQUE_PROFILE_ID
SERVER_PORT=25566
HEADLESS_TITLE=TGC Headless 02

Headless 03 would use another profile and another port such as 25567. Never duplicate profile IDs, UDP allocations, or display titles.

9. Mod placement rules

  • Backend server mods belong under /home/container/SPT/user/mods.

  • BepInEx client plugins required during a raid belong in every playable and headless client.

  • AI, spawn, progression, or simulation mods must be evaluated individually; a mod that runs only on a player's client may behave differently on a headless host.

  • After changing the mod set, validate one headless raid before copying the change to every instance.

10. Protect profiles before major changes

Stop the backend before taking a profile backup. From the Wings host:

sudo cp -a \
  /var/lib/pterodactyl/volumes/BACKEND_VOLUME_UUID/SPT/user/profiles \
  /var/lib/pterodactyl/volumes/BACKEND_VOLUME_UUID/SPT/user/profile-backup-before-change

Keep player profiles and headless identities together. If a clone accidentally starts with another host's identity, stop it immediately, correct PROFILE_ID, and confirm the profile directory before restarting.

Troubleshooting quick reference

Headless opens and immediately crashes

  • Verify EscapeFromTarkov.exe is directly inside /home/container/Headless.

  • Confirm DISPLAY_DEPTH=24.

  • Confirm the startup manager applies WINEDLLOVERRIDES="winhttp=n,b".

  • Compare the SPT, Fika, and plugin versions with the backend.

Headless cannot reach the backend

  • Confirm the backend is running first.

  • Re-check its Docker container address.

  • Use a complete headless BACKEND_URL, including scheme and port.

  • On the backend, keep BACKEND_IP as a bare advertised address.

  • Confirm LISTEN_ALL_NETWORKS=true.

Only one of two headless servers appears

  • Check for duplicated PROFILE_ID values.

  • Check for duplicated UDP allocations.

  • Give each instance a distinct HEADLESS_TITLE.

The process restarts after a raid

This is normal. The headless game process ends after the session, and the watchdog relaunches it so the instance can accept another raid.

Wine reports an unhandled page fault

The watchdog should detect the fault, wait for the configured grace period, terminate remaining Wine processes, and retry after RESTART_DELAY. Repeated faults usually indicate a bad HardCopy, display-depth problem, missing override, or version mismatch.

Final deployment checklist

  • Backend starts cleanly and reports Fika Server.

  • Backend advertises the correct public address.

  • Headless uses the current internal backend URL.

  • Every headless instance has a unique profile ID.

  • Every headless instance has a unique UDP allocation.

  • EscapeFromTarkov.exe is in the exact expected directory.

  • Xvfb runs at 24-bit depth.

  • -nographics -batchmode is present.

  • The Wine watchdog restarts a finished or failed client.

  • A playable client can join and finish a headless-hosted raid.

  • Profiles are backed up before cloning or changing mods.


TGC operational rule: prove one backend, one client, and one headless raid first. Scale only after that path is stable. Most multi-headless problems are duplicated identity, duplicated ports, version drift, or an incorrect internal backend address.