How to Make a Puck Dedicated Server (Linux and Windows, 2026)
Set up a Puck dedicated server with SteamCMD app 3481440, server_config.json, start_server.sh, port 30609 TCP and UDP, admins and game mode configs.
Updated Oct 1, 2026 · 6 min read
On this page
A Puck dedicated server is a free download from Steam that runs a rink without anyone sitting in the game hosting it. It is the step up from the in game Host Game button: it stays online on its own, it can run around the clock on a cheap VPS, and you control the tick rate, rules, admins and mods. This guide sets one up on Linux and Windows for the current build (B1235 and later), from SteamCMD to your first player connecting.
Short on time? A hosted Puck server is online in about 60 seconds from 2.99 USD a month, with nothing to forward. The quick start guide shows how.
What you need
- A machine that stays on while people play. Puck's dedicated server ships for Linux and Windows. Linux is the usual choice for a VPS.
- Very little memory: one server uses about 300 MB. A 1 GB VPS runs one comfortably, and 2 GB leaves room for a second instance.
- A fast CPU core. Puck runs its physics on the server, so it has to hold its tick rate (200 Hz by default) with a full rink.
- A connection with low ping to your players. In Puck the server's location matters more than almost anything else, so host near the people who play.
- Port 30609 open for TCP and UDP.
Step 1: Install SteamCMD
Linux (Debian or Ubuntu)
On Debian you need the non-free repository and 32 bit packages for SteamCMD:
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install steamcmd
On Debian, add non-free to your apt sources first if steamcmd is not found. Accept the Steam license prompt during install.
Windows
Download SteamCMD from Valve (steamcmd.zip), extract it to a folder such as C:\steamcmd and run steamcmd.exe once so it updates itself.
Step 2: Download the server (app 3481440)
The Puck dedicated server is Steam app 3481440 and downloads anonymously, no Steam account needed.
Linux:
steamcmd +force_install_dir /srv/puck +login anonymous +app_update 3481440 validate +quit
Windows:
steamcmd.exe +force_install_dir C:\puck-server +login anonymous +app_update 3481440 validate +quit
The download is around 200 MB. On Linux you get Puck, Puck_Data, start_server.sh and steamclient.so. On Windows you get Puck.exe, Puck_Data and steamclient.dll. Run the same command again to update after a Puck patch.
Step 3: Write server_config.json
In the server folder, create server_config.json. These are the server's own defaults, with a name you choose:
{
"port": 30609,
"name": "My Puck Server",
"maxPlayers": 12,
"password": null,
"tickRate": 200,
"isPublic": true,
"useVoip": false,
"useWhitelist": false,
"mods": [],
"gameMode": "public",
"level": "default"
}
| Key | Meaning |
|---|---|
port |
Game port. UDP for gameplay and TCP on the same number for the server browser ping. |
name |
The name in the server browser. Unity rich text tags work, but keep it readable. |
maxPlayers |
Slots, spectators included. 12 fits 6v6 with goalies. |
password |
null for an open server, or a string. |
tickRate |
Simulation rate in Hz. 200 is what official servers use. |
isPublic |
true lists the server in the browser. |
useVoip |
In game voice chat. |
useWhitelist |
Only Steam IDs in whitelisted_steam_ids.json can join. |
mods |
Steam Workshop mods, see how to add mods to a Puck server. |
gameMode |
public or competitive. |
Every key is covered in more depth in Puck server config explained. The server refuses to start if this file is not valid JSON, and the log names the file, line and key that broke. The parser is strict: no comments, no trailing commas, and text values like name and password must be in quotes.
Step 4: Start the server
Linux
Always start through the script, not the binary, because it sets the library path so the server can load the Steam API:
cd /srv/puck
chmod +x start_server.sh Puck
./start_server.sh --serverConfigPath ./server_config.json
Windows
Open a command prompt in the server folder and run:
Puck.exe --serverConfigPath server_config.json
The server signs in to Puck's backend, downloads any server mods and then logs a line like Puck B1235 is ready to accept clients on 0.0.0.0:30609!. Until that line appears, players who connect see "Server is still starting".
Useful command line options, all with defaults in the server folder:
| Option | Default |
|---|---|
--serverConfigPath |
./server_config.json |
--publicGameModeConfigPath |
./public_game_mode_config.json |
--competitiveGameModeConfigPath |
./competitive_game_mode_config.json |
--adminSteamIdsPath |
./admin_steam_ids.json |
--bannedSteamIdsPath |
./banned_steam_ids.json |
--whitelistedSteamIdsPath |
./whitelisted_steam_ids.json |
--logPath |
./Logs/Puck.log |
Step 5: Keep it running on Linux
A systemd service restarts the server if it crashes and starts it at boot. Create /etc/systemd/system/puck.service:
[Unit]
Description=Puck Dedicated Server
After=network.target
[Service]
WorkingDirectory=/srv/puck
User=puck
ExecStart=/srv/puck/start_server.sh --serverConfigPath /srv/puck/server_config.json
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Create the user and start it:
sudo adduser --system --group --no-create-home puck
sudo chown -R puck:puck /srv/puck
sudo systemctl daemon-reload
sudo systemctl enable --now puck
journalctl -u puck -f
To run a second rink, copy the folder, change port to 30610 and make a second service.
Step 6: Open port 30609 TCP and UDP
Puck uses one port number for two protocols: UDP for the game itself and TCP for the ping and server details the browser shows.
- Allow it through the server's firewall. On Ubuntu with ufw:
sudo ufw allow 30609/tcpandsudo ufw allow 30609/udp. On Windows, allowPuck.exewhen the firewall asks, or add inbound rules for TCP and UDP 30609. - If the server is at home, forward TCP and UDP 30609 on your router to the server's local IP. Our port forwarding guide walks through the router side.
- If your internet provider uses CGNAT, port forwarding cannot work. Compare your router's WAN IP with your public IP, and if they differ, use a VPS or a hosted server instead.
Step 7: Add admins and game rules
Admins are SteamID64s in admin_steam_ids.json, a plain JSON list:
["76561198000000000", "76561198000000001"]
The server creates the file if it is missing and reloads it as soon as you save. Admins use chat commands like /kick, /ban, /pause and /skip, listed in Puck admin commands.
Game rules live in public_game_mode_config.json (and competitive_game_mode_config.json for league play). For example, 10 minute periods with a 30 second warmup. Keep every phase in the map, because the file replaces the built in one rather than adding to it:
{
"phaseDurationMap": {
"None": 0,
"Warmup": 30,
"PreGame": 10,
"FaceOff": 4,
"Play": 600,
"BlueScore": 4,
"RedScore": 4,
"Replay": 9,
"Intermission": 10,
"GameOver": 30,
"PostGame": 10
},
"spawnDelay": 10,
"maxPeriods": 3,
"goalSlowMotion": true,
"goalieCreaseProtection": true
}
If a game mode file is broken, the server logs the error and falls back to the default rules instead of refusing to start, so check the log after editing.
How players connect
Players open Server Browser in Puck and search for your server's name, or click Direct Connect and type your public IP and port 30609 in the two boxes. Joining from home needs no port forwarding on the player's side. Full steps are in how to join a Puck server, and connection problems in Puck server not showing up or can't connect.
The easy way
Running Puck yourself is a light job, but it still means a machine that stays on, JSON edited by hand, port 30609 forwarded for two protocols, your home IP shared with every player and a SteamCMD update after every patch.
A GamezServers Puck server handles all of that. Pick a plan from 2.99 USD a month for 12 slots, pay, and the rink is live in about 60 seconds with period length, game mode, admins and the whitelist as settings in the panel, updates on every restart and one click backups.
Skip the setup. Your own Puck server.
Then $2.99/mo. Just trying it? $0.75 for 3 days