Hosting Guides

How to Build a High Performance CS2 Server with Pterodactyl (Ubuntu 24.04)

5 min readUbuntu 24.04PterodactylSource
Once your server is online, jump to the Counter-Strike 2 command and config reference.

If you have ever tried to babysit a bare metal srcds_run process inside tmux, you already know why isolated, reproducible containers are the better answer for any community CS2 deployment. Pterodactyl wraps each game server in a dedicated Docker container, hands you a clean web panel for config, console, file management, and database control, and exposes a daemon called Wings that brokers everything to the Docker socket on the host.

About the "128 tick" question: CS2 ships with a hardcoded sub-tick architecture, so you cannot ask the engine for a higher tickrate. What you can still influence is how aggressively the server sends and receives snapshots, how fast clients are allowed to interpolate, and how cleanly the host can deliver those snapshots without jitter. Pair high frequency hardware (modern Zen 4 or 14th gen Intel cores, low latency DDR5, and a tuned 1 Gbps uplink) with the launch parameters at the bottom of this guide and you will get the crisp registration that veterans associate with legacy 128 tick boxes.

Prerequisites

  • A fresh Ubuntu 24.04 LTS install on a VPS or dedicated box.
  • Root SSH access, or a sudo capable user.
  • At least 4 GB of RAM (8 GB recommended for 24 slot servers).
  • A domain or subdomain you can point at the panel host (optional but recommended).

Step 1: System Preparation

Before installing anything, refresh the package index and pull any pending security updates. A clean baseline avoids version skew when Pterodactyl pulls in PHP, MariaDB, Redis, and Docker. Install the small set of utilities you will reach for during the rest of the build (curl, gnupg, certificate handling, and a process supervisor).

root@host
apt update && apt upgrade -y
apt install -y curl wget tar unzip gnupg ca-certificates lsb-release software-properties-common

Step 2: Firewall Configuration

UFW (Uncomplicated Firewall) sits in front of nftables and gives you a sane default deny posture without the syntax tax. You only need four holes punched: SSH, the web panel on 80 and 443, and the CS2 game ports on 27015 (both UDP for traffic and TCP for the RCON socket). Lock everything else.

root@host
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 27015/udp
ufw allow 27015/tcp
ufw --force enable
ufw status verbose

Step 3: Installing the Pterodactyl Panel and Wings

Pterodactyl is split into two services. The Panel is a PHP and Laravel web application backed by MariaDB and Redis, and it gives administrators and end users the UI for creating servers, editing configuration, browsing files, and watching the console. Wings is a small Go daemon that lives on every node, listens to instructions from the Panel, and drives the Docker socket to start, stop, and update game server containers.

The official maintainers ship a vetted installer that handles dependencies, the database, the queue worker, and the systemd unit. Run the Panel installer first on the host you want to expose to the web.

Install Pterodactyl Panel
bash <(curl -s https://pterodactyl-installer.se)

When the installer prompts you, pick "Install the panel", provide your FQDN, and let it generate a Let's Encrypt certificate if the domain already resolves to this host. Once it finishes, log in with the admin credentials it prints to the console and confirm you can reach the dashboard at https://your.domain.

Wings runs on every node that should host containers. On a single box build it is the same machine you just configured. Re run the installer and pick the Wings option, which installs Docker CE, sets up the daemon, and writes the systemd unit.

Install Wings and Docker
bash <(curl -s https://pterodactyl-installer.se)
systemctl enable --now wings
systemctl status wings --no-pager

Back in the Panel, navigate to Admin, Nodes, Create New. Give the node a name, set the FQDN to the same host, paste the auto generated configuration into /etc/pterodactyl/config.yml, then restart Wings to register the node.

Register the node
systemctl restart wings
journalctl -u wings -f

Step 4: Deploying the CS2 Server Egg

A Pterodactyl "Egg" is a JSON template that describes how to install, configure, and launch a specific game. The community maintains an actively updated Counter Strike 2 Egg that handles the SteamCMD bootstrap, mounts the correct working directory, and exposes the startup variables you actually want to tweak.

From the Panel: go to Admin, Nests, Import Egg, upload the CS2 Egg JSON, then create an Allocation pointing at the node IP on port 27015. Create a new Server, pick the Counter Strike 2 Egg from the Source Game Server nest, attach the allocation, and assign at least 2 vCPU and 4 GB of RAM. Pterodactyl will run SteamCMD inside the container, pull the dedicated server files for App ID 730, and drop you at the console.

The defaults are conservative. Replace the startup string with the following block to push the snapshot rate ceiling, tighten the client interpolation window, and pre warm the dedicated server logging that you will want when triaging tick smoothness reports from players.

CS2 startup parameters
./game/bin/linuxsteamrt64/cs2 -dedicated +map de_dust2 \
-port 27015 +sv_setsteamaccount $STEAM_TOKEN \
+game_type 0 +game_mode 1 \
-tickrate 128 -usercon +sv_logfile 1 \
+sv_minrate 196608 +sv_maxrate 786432 \
+sv_mincmdrate 128 +sv_maxcmdrate 128 \
+sv_minupdaterate 128 +sv_maxupdaterate 128 \
+fps_max 600 +mp_match_end_restart 1 \
+exec server.cfg

Note that -tickrate 128 is preserved as a compatibility hint, even though sub-tick supersedes the legacy fixed tickrate. The rate, cmdrate, and updaterate ceilings remain meaningful because they raise the bandwidth and frequency caps that the sub-tick simulation is allowed to push to each client. Save the server, hit Start, and watch the console for the "VAC secure" line.

Conclusion

That is the entire pipeline. Ubuntu 24.04 underneath, UFW in front, Pterodactyl Panel and Wings orchestrating a Dockerized CS2 process tuned for high frequency snapshot delivery. To verify the build, fire up Counter Strike 2, drop the developer console with the tilde key, and run:

In game developer console
connect your.server.ip:27015

You should land on de_dust2 within a few seconds. From here, layer on Sourcemod, MatchZy, or your preferred plugin stack inside the same container and let the panel handle restarts, backups, and console access. The infrastructure is now boring in the best possible way, which is exactly what a community server should be.