How to Run Multiple CS 1.6 Servers on One VPS

September 24, 2025 Daemon666 9 min read 18 Aufrufe

One VPS can comfortably host several CS 1.6 servers — the engine is light and a modern core has cycles to spare. The rules are simple: each instance needs its own UDP port, its own working directory for logs and configs, and its own process supervisor. This guide sets up three, but the pattern scales to as many as your CPU and bandwidth allow.

1. One base install, many instances

A full App 90 install is a few hundred megabytes, and copying it per server wastes disk and makes updates painful. Install it once, then create per-instance directories that share the read-only engine and mod files via hardlinks, keeping only configs and logs separate. Start from a working base at /home/steam/hlds (see the SteamCMD install), then:

cd /home/steam
cp -al hlds server1
cp -al hlds server2
cp -al hlds server3

cp -al makes an archive copy with hardlinks: the binaries and maps occupy disk once, but each directory can hold its own cstrike/server.cfg, logs/, and banned.cfg. When you re-run app_update 90 on the base, hardlinked files update in place; regenerate the copies after a major engine change to be safe.

2. Give each instance its own port and identity

The engine's UDP port is set with -port. Use a clean numbering scheme so the firewall and your memory both stay sane:

InstanceDirectoryPort
server1/home/steam/server127015
server2/home/steam/server227016
server3/home/steam/server327017

Each instance's cstrike/server.cfg needs a distinct hostname and its own rcon_password. If the VPS has multiple public IPs you can instead bind each server to a different IP with -ip and reuse port 27015; most people just use different ports on one IP.

3. Start them by hand first

Prove each one boots before automating anything:

cd /home/steam/server1
./hlds_run -game cstrike -strictportbind -ip 0.0.0.0 -port 27015 \
  +map de_dust2 +maxplayers 20 +sv_lan 0

cd /home/steam/server2
./hlds_run -game cstrike -strictportbind -ip 0.0.0.0 -port 27016 \
  +map de_dust2 +maxplayers 20 +sv_lan 0

-strictportbind is important here: without it, a second server started on an already-used port silently grabs the next free one, and you end up with two servers on 27016 and none on 27015, wondering why a client cannot connect.

4. Manage them with a systemd template

Instead of one unit per server, write a single template unit parameterised by directory and port. Create /etc/systemd/system/[email protected]:

[Unit]
Description=CS 1.6 server (%i)
After=network.target

[Service]
Type=simple
User=steam
WorkingDirectory=/home/steam/%i
ExecStart=/home/steam/%i/hlds_run -game cstrike -strictportbind \
  -ip 0.0.0.0 -port ${PORT} +map de_dust2 +maxplayers 20 +sv_lan 0
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Because each instance needs a different port, drop an override per instance:

sudo systemctl edit hlds@server2
[Service]
Environment=PORT=27016

Then enable and start each — the full template approach is covered in the systemd service guide:

sudo systemctl enable --now hlds@server1
sudo systemctl enable --now hlds@server2
sudo systemctl enable --now hlds@server3

5. Open the ports

sudo ufw allow 27015:27017/udp
sudo ufw allow 27015:27017/tcp

The TCP range is for RCON. If you also run HLTV per instance, allocate a second block (27020+) and open it too — see which ports to open.

Common errors

  • Two servers, one shows, one does not — a port collision the engine resolved silently. Add -strictportbind and give each a unique -port.
  • Both servers write to the same log — they share a cstrike/ directory. Each instance needs its own directory (the cp -al copies above).
  • RCON controls the wrong server — same rcon_password and you connected to the wrong port. Use distinct passwords and connect by port.
  • High load with several full servers — you set an aggressive sys_ticrate/-pingboost on every instance. FPS scales per process; do not run four servers each pinned at 1000 FPS on a two-core box.

Plan the resources honestly

Instances are cheap in disk but not free in CPU and bandwidth. A busy 32-slot server pushes real traffic, and running several full ones on a low-core VPS with an aggressive -pingboost or high sys_ticrate on each will starve them all. A useful rule of thumb: budget one physical core per busy public server if you want stable server FPS, and check your provider's bandwidth cap — several full servers can move a surprising amount of egress. Maps are shared through the hardlinked copies, so adding a custom map to the base and re-running cp -al propagates it without duplicating disk. Keep each instance's rcon_password distinct and stored only in that instance's cstrike/server.cfg, readable only by the steam user, so one leaked password does not hand over every server.

Verification

systemctl status 'hlds@*'
ss -lunp | grep hlds

You should see one hlds_linux bound per port (27015, 27016, 27017). Connect a client to each port in turn and confirm the hostname differs. When all instances answer independently and survive a reboot, the multi-server setup is done.

Mitwirkende: Daemon666 ✦
Teilen: