Dedicated Linux server: Difference between revisions

From TF2 Classic Wiki
Jump to navigation Jump to search
(Do a basic port of Raizo's article, updating and changing some things to make it workable for 2.0.3. Still needs information on exactly how you connect to your server by SFTP, importing some of the old FAQ, and a Sourcemod guide, but this is fine for now.)
 
m (Added indention to the note. Removed "Note".)
 
(28 intermediate revisions by 3 users not shown)
Line 1: Line 1:
''Note: This was adapted and revised from a guide written by Raizo, which can be found here: https://iraizo.github.io/tf2-classic-linux-server-tutorial/''
:''This article was adapted and revised from a guide written by Raizo, the original of which can be found here: https://blog.raizo.dev/posts/tf2-classic-linux-server-tutorial/''


= Prerequisites =
== Prerequisites ==
* A Linux server running Ubuntu Server<sup>*</sup> on an x86_64 CPU. You cannot easily run SRCDS on any other architecture besides an x86_64 CPU. Box64/Box86 may work for ARM processors (e.g. Raspberry Pis) but that's complex, and not covered here.
* A Linux server running Ubuntu Server<sup>*</sup> on an x86_64 CPU. You cannot easily run SRCDS on any other architecture besides an x86_64 CPU. Box64/Box86 may work for ARM processors (e.g. Raspberry Pis) but that's complex, and not covered here.
* A SFTP/SSH client (PuTTY, Termius, FileZilla, MobaXterm)
* A SFTP/SSH client (PuTTY, Termius, FileZilla, MobaXterm)
Line 7: Line 7:
* A minimum of a 10Mbps upload speed if you intend on hosting a server over the Internet. No need to worry for LAN servers.
* A minimum of a 10Mbps upload speed if you intend on hosting a server over the Internet. No need to worry for LAN servers.


This guide was written for and tested on Ubuntu Server 20.04 LTS, however any Debian-based distro should work similarly and fine using this guide.
<sup>*</sup>'''Note''': This guide was written for and tested on Ubuntu Server 22.04 LTS, however any Debian-based distro should work similarly and fine using this guide.


''*Ubuntu 20.04 LTS is the first Ubuntu version that starts to phase out many i386 libraries from Focal Fossa repos and future Ubuntu versions. Many Source games still rely on i386 libraries. While TF2C, Steam, and SteamCMD are known to work fine, it is possible other Source games and custom plugins and addons may or may not work properly without utilization of PPAs.
=== Reading this article ===
''
= Reading this article =
<!-- Originally from https://wiki.teamfortress.com/wiki/Linux_dedicated_server#Reading_this_article -->
<!-- Originally from https://wiki.teamfortress.com/wiki/Linux_dedicated_server#Reading_this_article -->
This article has been written according to standard Linux terminal documentation syntax, meaning the following:
This article has been written according to standard Linux terminal documentation syntax, meaning the following:
Line 21: Line 19:
Some commands are listed in-line with the rest of a paragraph and lack this symbol, in which case you should run the command as whichever account you're currently logged in with.
Some commands are listed in-line with the rest of a paragraph and lack this symbol, in which case you should run the command as whichever account you're currently logged in with.


= Creating a steam user for SteamCMD and Source SDK Base 2013 Dedicated Server =
=== Creating a steam user for SteamCMD and Source SDK Base 2013 Dedicated Server ===
Pick a directory to install your server into. Industry standard is usually in <code>/opt</code>, but <code>/home</code> may be easier for you. If you want to use a directory in <code>/home</code>, omit the <code>-d</code> option as useradd will create a directory in <code>/home</code> with the user’s username, ours being <code>steam</code>. We’ll pick <code>/opt/tf2classic</code>.
Pick a directory to install your server into. Industry standard is usually in <code>/opt</code>, but <code>/home</code> may be easier for you. If you want to use a directory in <code>/home</code>, omit the <code>-d</code> option as useradd will create a directory in <code>/home</code> with the user’s username, ours being <code>steam</code>. We’ll pick <code>/opt/tf2classic</code>.


Create a user with that home directory and give it a strong password:
Create a user with that home directory and give it a strong password:


<code>
<pre>
<nowiki>#</nowiki> useradd -m -d /opt/tf2classic -s /usr/bin/bash steam
# useradd -m -d /opt/tf2classic -s /usr/bin/bash steam
 
# passwd steam
<nowiki>#</nowiki> passwd steam
</pre>
</code>


<code>-m</code> creates a home directory for it, <code>-d /opt/tf2classic</code> specifies where our home directory will be, and <code>-s /usr/bin/bash</code> sets the shell to bash.
<code>-m</code> creates a home directory for it, <code>-d /opt/tf2classic</code> specifies where our home directory will be, and <code>-s /usr/bin/bash</code> sets the shell to bash.


= Installing Source SDK Base 2013 DS, SteamCMD, and dependencies =
=== Installing Source SDK Base 2013 DS, SteamCMD, and dependencies ===
The SteamCMD package is in the multiverse repos. TF2Classic and SteamCMD require i386 (32-bit) libraries to function. You also need 7-Zip to extract TF2Classic.
The SteamCMD package is in the multiverse repos. TF2Classic and SteamCMD require i386 (32-bit) libraries to function. You also need 7-Zip to extract TF2Classic.


<code>
<pre>
<nowiki>#</nowiki> add-apt-repository multiverse
# add-apt-repository multiverse
# dpkg --add-architecture i386
# apt update
</pre>


<nowiki>#</nowiki> dpkg --add-architecture i386
Install SteamCMD, and miscellaneous packages that we'll be using.


<nowiki>#</nowiki> apt update
<pre>
</code>
# apt install steamcmd unzip aria2 tilde lib32z1 libncurses5:i386 libbz2-1.0:i386 lib32gcc-s1 lib32stdc++6 libtinfo5:i386 libcurl3-gnutls:i386 libsdl2-2.0-0:i386 libcurl4-gnutls-dev libcurl4-gnutls-dev:i386
 
</pre>
Install SteamCMD, 7-Zip, and miscellaneous packages that we'll be using.
''<sup>*</sup>'''Note''':See [https://developer.valvesoftware.com/wiki/SteamCMD#Package_From_Repositories|Valve Developer Wiki SteamCMD Repository Packages] if your distro is having issues getting steamcmd.
 
''
<code>
<nowiki>#</nowiki> apt install steamcmd 7zip aria2 tilde lib32z1 libncurses5:i386 libbz2-1.0:i386 lib32gcc1-s1 lib32stdc++6 libtinfo5:i386 libcurl3-gnutls:i386 libsdl2-2.0-0:i386
</code>


Login to the steam user you created:
Login to the steam user you created:


<code># su - steam</code>
<pre># su - steam</pre>


Run <code>steamcmd</code> and let it update. When it’s finished updating and displays a prompt, login anonymously by typing and running: <code>login anonymous</code>
Run <code>steamcmd</code> and let it update. When it’s finished updating and displays the main SteamCMD shell, run <code>force_install_dir /opt/tf2classic/server</code> to choose the directory for the Source SDK Base 2013 Dedicated server to install into. This path can be anything, just make sure you have access to it.


We will set a directory to install Source SDK Base 2013 DS to.
Login anonymously by typing and running: <code>login anonymous</code>
Run <code>force_install_dir /opt/tf2classic/server</code> in SteamCMD to choose the directory for the server to install into. This path can be anything, just make sure you have access to it.


Then run <code>app_update 244310 validate</code> in SteamCMD to install Source SDK Base 2013 DS.
Then run <code>app_update 244310 validate</code> in SteamCMD to install Source SDK Base 2013 DS.
Line 64: Line 60:
Give it a few, and when it’s finished we can run <code>exit</code>.
Give it a few, and when it’s finished we can run <code>exit</code>.


= Downloading TF2 Classic =
== Downloading TF2 Classic ==
The fastest way to download TF2Classic is to use a command-line download manager called Aria2 in combination with a "Metalink" which downloads from many mirrors at once.
The fastest way to download TF2Classic is to use TF2CDownloader.


Run:
Run:


<code>
<pre>
aria2c https://tf2classic.org/tf2c/tf2classic-2.0.3.meta4
$ wget https://github.com/tf2classic/TF2CDownloader/releases/latest/download/TF2CDownloaderLinux
</code>
$ chmod +x ./TF2CDownloaderLinux
 
$ ./TF2CDownloaderLinux
It may produce some harmless errors in case any of the mirrors in the Metalink are currently inactive, but it will download the <code>tf2classic-2.0.3.zip</code> file rapidly, and it will automatically verify that the downloaded file isn't corrupted.
</pre>


Extract the downloaded file by running <code>7zz x tf2classic-2.0.3.zip</code>
And follow the prompts.


Then finally move the directory into your SDK 2013 MP folder:  
You'll need to move the extracted directory into your SDK 2013 MP folder:  


<code>mv tf2classic /opt/tf2classic/server/</code>
<pre>mv tf2classic /opt/tf2classic/server/</pre>


= Server Configuration =
=== Server Configuration ===
Generate your server config(s) on cfg.tf.
Generate your server config(s) on [https://cfg.tf/ cfg.tf].


Make sure the server type is set to “Internet and LAN” if you want players outside your LAN to be able to join (you may need to port forward if you’re on consumer broadband or open ports on your firewall).
Make sure the server type is set to “Internet and LAN” if you want players outside your LAN to be able to join (you may need to port forward if you’re on consumer broadband or open ports on your firewall).
Line 88: Line 84:
Upload the generated ZIP file to your server using SFTP, unzip the folder using:
Upload the generated ZIP file to your server using SFTP, unzip the folder using:


<code>7zz x <archive>.zip</code>
<pre>unzip <archive>.zip</pre>


And merge the <code>cfg</code> folder with <code>/opt/tf2classic/server/tf2classic/cfg/</code>.
And merge the <code>cfg</code> folder with <code>/opt/tf2classic/server/tf2classic/cfg/</code>.


= Creating the server script =
=== Create symlinks to missing shared objects. ===
Valve changed some shared object file names in the SDK and the objects we’re given have not adapted to the new names. Since these are simply renames, we can symlink them.
'''Your server will not start without doing this.'''
 
Enter the bin directory by typing, exactly:
 
<code>
$ cd bin
</code>
 
Run the following commands to create the symlinks in the bin folder:
 
<pre>
$ ln -s datacache_srv.so datacache.so
$ ln -s dedicated_srv.so dedicated.so
$ ln -s engine_srv.so engine.so
$ ln -s materialsystem_srv.so materialsystem.so
$ ln -s replay_srv.so replay.so
$ ln -s scenefilecache_srv.so scenefilecache.so
$ ln -s shaderapiempty_srv.so shaderapiempty.so
$ ln -s studiorender_srv.so studiorender.so
$ ln -s vphysics_srv.so vphysics.so
$ ln -s soundemittersystem_srv.so soundemittersystem.so
</pre>
 
If you've manually installed TF2 Classic instead of using the automatic installer, make sure to symlink these files too, inside TF2 Classic's bin folder:
 
<pre>
$ cd ../tf2classic/bin
$ rm server_srv.so
$ ln -s server.so server_srv.so
</pre>
 
== Running the server ==
 
=== Creating the server script ===
Change into the server directory with:
Change into the server directory with:


<code>$ cd /opt/tf2classic/server/</code>
<pre>$ cd /opt/tf2classic/server/</pre>


Create a script to run the server with one simple command. Use any text editor of your choice to create runserver.sh where srcds_run is located. For the sake of those unfamiliar with terminal text editing, we'll be using Tilde. Run:
Create a script to run the server with one simple command. Use any text editor of your choice to create runserver.sh where srcds_run is located. For the sake of those unfamiliar with terminal text editing, we'll be using nano. Run:


<code>$ tilde runserver.sh</code>
<pre>$ nano runserver.sh</pre>


Fill it with this line (you may be able to paste using Ctrl-Shift-V):
Fill it with this line (you may be able to paste using <code>Shift+Insert</code>):


<code>./srcds_run -console -game tf2classic +map pl_upward +maxplayers 24</code>
<pre>./srcds_run -console -game tf2classic +map pl_upward +maxplayers 24</pre>


Feel free to change the map and maxplayers. There are more arguments, but we’ll keep it basic.
Feel free to change the map and maxplayers. There are more arguments, but we’ll keep it basic.


Save the file by clicking "File" -> "Exit", and confirming to save your changes. You can also press Ctrl-Q to accomplish this with your keyboard alone, if mouse inputs aren't passed through.
Save the file by clicking <code>CRTL+X</code>, and then <code>Y</code> to write your changes.


Now, make the script executable with:
Now, make the script executable with:


<code>
<pre>
$ chmod +x runserver.sh
$ chmod +x runserver.sh
</code>
</pre>
 
Finally, all you need to do to start the server is run <code>./runserver.sh</code>!
 
If you want it to run even after closing the terminal window, run <code>nohup ./runserver.sh &</code> followed by <code>disown</code>


= Create symlinks to missing shared objects. =
=== Systemd & Crontab for automated start, restart and updating ===
Valve changed some shared object file names in the SDK and the objects we’re given have not adapted to the new names. Since these are simply renames, we can symlink them.
For easier automation of server restarts, updating, and booting alongside the system, you may use systemd, which is the default init system for most modern Linux distros and cronjobs.
'''Your server will not start without doing this.'''


Enter the bin directory by typing, exactly:
Create file <code>ssdk2013mp-update</code> and fill in the following
<pre>
@ShutdownOnFailedCommand 1 //set to 0 if updating multiple servers at once
@NoPromptForPassword 1
login anonymous
app_update 244310
quit
</pre>


<code>
Make it executable with <code>chmod +x ssdk2013mp-update</code>
cd bin
</code>


Run the following commands to create the symlinks in the bin folder:
This script will update the underlying Source SDK 2013 MP Dedicated Server, you may execute it by itself, but in this case we will use it for automatic updates.


<code>
Next, create a service file in <code>/etc/systemd/system/</code>
$ ln -s datacache_srv.so datacache.so


$ ln -s dedicated_srv.so dedicated.so
Example <code>tf2classic.service</code>:
<pre>
[Unit]
Description=TF2Classic
After=network-online.target
Wants=network-online.target


$ ln -s engine_srv.so engine.so
[Service]
Type=forking
User=steam
WorkingDirectory=/home/tf2classic
RemainAfterExit=yes
ExecStartPre=/usr/games/steamcmd +runscript /opt/tf2classic/ssdkb2013mp-update
ExecStartPre=/opt/tf2classic/TF2CDownloaderLinux --update
ExecStart=/opt/tf2classic/server/srcds_run -console -game tf2classic +map tr_walkway_fastcat_v1 -port 27020 +maxplayers 32 +sv_setsteamaccount XXXXXXX
TimeoutStartSec=infinity
Restart=always


$ ln -s materialsystem_srv.so materialsystem.so
[Install]
WantedBy=multi-user.target
</pre>


$ ln -s replay_srv.so replay.so
Then, enable the service to start with the init system:
<pre>
# systemctl enable tf2classic.service
</pre>


$ ln -s scenefilecache_srv.so scenefilecache.so
Next, switch to the <code>root</code> user using <code>sudo su</code> and execute <code>crontab -e</code>. This is where you can set cronjobs, include something like the following:


$ ln -s shaderapiempty_srv.so shaderapiempty.so
<pre>
# Restart and update check for TF2Classic every day at 4 AM.


$ ln -s studiorender_srv.so studiorender.so
0 4 * * * systemctl restart tf2classic.service
</pre>


$ ln -s vphysics_srv.so vphysics.so
You may create as many services as you have TF2C servers but remember to name the service files uniquely, enable them in <code>systemctl</code>, and add them to the <code>crontab</code>.  


$ ln -s soundemittersystem_srv.so soundemittersystem.so
=== Systemd manual start, stop, restart/update ===
</code>


= Running the server =
If you don't wish to use the service files above to automatically boot servers, or you need to perform these actions for maintenance: you may issue commands to manually ''start'', ''stop'', ''restart'', or ''update'' the server(s) through systemd.  
Finally, all you need to do to start the server is run <code>./runserver.sh</code>!


If you want it to run even after closing the terminal window, run <code>nohup ./runserver.sh &</code> followed by <code>disown</code>
<pre>
# systemctl restart tf2classic # in case you need to restart manually or to grab updates!!
# systemctl stop tf2classic # in case you need to stop the server manually
# systemctl start tf2classic # in case you need to start the server manually
# systemctl disable tf2classic # in case you need to stop the server from booting as your system initializes
# systemctl enable tf2classic # in case you need to start the server to boot as your system initializes
</pre>


More advanced users will likely want to run it using GNU Screen, or using a systemd service, which will be documented here eventually.
''</br>See also [[Dedicated_Linux_server_extras|Dedicated Linux Server Extras]].''
[[Category:Guides]]

Latest revision as of 12:53, 23 April 2024

This article was adapted and revised from a guide written by Raizo, the original of which can be found here: https://blog.raizo.dev/posts/tf2-classic-linux-server-tutorial/

Prerequisites

  • A Linux server running Ubuntu Server* on an x86_64 CPU. You cannot easily run SRCDS on any other architecture besides an x86_64 CPU. Box64/Box86 may work for ARM processors (e.g. Raspberry Pis) but that's complex, and not covered here.
  • A SFTP/SSH client (PuTTY, Termius, FileZilla, MobaXterm)
  • At least 16GB of free storage
  • A minimum of a 10Mbps upload speed if you intend on hosting a server over the Internet. No need to worry for LAN servers.

*Note: This guide was written for and tested on Ubuntu Server 22.04 LTS, however any Debian-based distro should work similarly and fine using this guide.

Reading this article

This article has been written according to standard Linux terminal documentation syntax, meaning the following:

A command prefixed by # (a hashtag) is meant to be run as root. In this article, we're assuming that you're using a VPS and logged in as the root account to start with.

A command prefixed by $ (a dollar sign) is meant to be run as a regular user without root permissions.

Some commands are listed in-line with the rest of a paragraph and lack this symbol, in which case you should run the command as whichever account you're currently logged in with.

Creating a steam user for SteamCMD and Source SDK Base 2013 Dedicated Server

Pick a directory to install your server into. Industry standard is usually in /opt, but /home may be easier for you. If you want to use a directory in /home, omit the -d option as useradd will create a directory in /home with the user’s username, ours being steam. We’ll pick /opt/tf2classic.

Create a user with that home directory and give it a strong password:

# useradd -m -d /opt/tf2classic -s /usr/bin/bash steam
# passwd steam

-m creates a home directory for it, -d /opt/tf2classic specifies where our home directory will be, and -s /usr/bin/bash sets the shell to bash.

Installing Source SDK Base 2013 DS, SteamCMD, and dependencies

The SteamCMD package is in the multiverse repos. TF2Classic and SteamCMD require i386 (32-bit) libraries to function. You also need 7-Zip to extract TF2Classic.

# add-apt-repository multiverse
# dpkg --add-architecture i386
# apt update

Install SteamCMD, and miscellaneous packages that we'll be using.

# apt install steamcmd unzip aria2 tilde lib32z1 libncurses5:i386 libbz2-1.0:i386 lib32gcc-s1 lib32stdc++6 libtinfo5:i386 libcurl3-gnutls:i386 libsdl2-2.0-0:i386 libcurl4-gnutls-dev libcurl4-gnutls-dev:i386

*Note:See Developer Wiki SteamCMD Repository Packages if your distro is having issues getting steamcmd.

Login to the steam user you created:

# su - steam

Run steamcmd and let it update. When it’s finished updating and displays the main SteamCMD shell, run force_install_dir /opt/tf2classic/server to choose the directory for the Source SDK Base 2013 Dedicated server to install into. This path can be anything, just make sure you have access to it.

Login anonymously by typing and running: login anonymous

Then run app_update 244310 validate in SteamCMD to install Source SDK Base 2013 DS.

Give it a few, and when it’s finished we can run exit.

Downloading TF2 Classic

The fastest way to download TF2Classic is to use TF2CDownloader.

Run:

$ wget https://github.com/tf2classic/TF2CDownloader/releases/latest/download/TF2CDownloaderLinux
$ chmod +x ./TF2CDownloaderLinux
$ ./TF2CDownloaderLinux

And follow the prompts.

You'll need to move the extracted directory into your SDK 2013 MP folder:

mv tf2classic /opt/tf2classic/server/

Server Configuration

Generate your server config(s) on cfg.tf.

Make sure the server type is set to “Internet and LAN” if you want players outside your LAN to be able to join (you may need to port forward if you’re on consumer broadband or open ports on your firewall).

Upload the generated ZIP file to your server using SFTP, unzip the folder using:

unzip <archive>.zip

And merge the cfg folder with /opt/tf2classic/server/tf2classic/cfg/.

Create symlinks to missing shared objects.

Valve changed some shared object file names in the SDK and the objects we’re given have not adapted to the new names. Since these are simply renames, we can symlink them. Your server will not start without doing this.

Enter the bin directory by typing, exactly:

$ cd bin

Run the following commands to create the symlinks in the bin folder:

$ ln -s datacache_srv.so datacache.so
$ ln -s dedicated_srv.so dedicated.so
$ ln -s engine_srv.so engine.so
$ ln -s materialsystem_srv.so materialsystem.so
$ ln -s replay_srv.so replay.so
$ ln -s scenefilecache_srv.so scenefilecache.so
$ ln -s shaderapiempty_srv.so shaderapiempty.so
$ ln -s studiorender_srv.so studiorender.so
$ ln -s vphysics_srv.so vphysics.so
$ ln -s soundemittersystem_srv.so soundemittersystem.so

If you've manually installed TF2 Classic instead of using the automatic installer, make sure to symlink these files too, inside TF2 Classic's bin folder:

$ cd ../tf2classic/bin
$ rm server_srv.so
$ ln -s server.so server_srv.so

Running the server

Creating the server script

Change into the server directory with:

$ cd /opt/tf2classic/server/

Create a script to run the server with one simple command. Use any text editor of your choice to create runserver.sh where srcds_run is located. For the sake of those unfamiliar with terminal text editing, we'll be using nano. Run:

$ nano runserver.sh

Fill it with this line (you may be able to paste using Shift+Insert):

./srcds_run -console -game tf2classic +map pl_upward +maxplayers 24

Feel free to change the map and maxplayers. There are more arguments, but we’ll keep it basic.

Save the file by clicking CRTL+X, and then Y to write your changes.

Now, make the script executable with:

$ chmod +x runserver.sh

Finally, all you need to do to start the server is run ./runserver.sh!

If you want it to run even after closing the terminal window, run nohup ./runserver.sh & followed by disown

Systemd & Crontab for automated start, restart and updating

For easier automation of server restarts, updating, and booting alongside the system, you may use systemd, which is the default init system for most modern Linux distros and cronjobs.

Create file ssdk2013mp-update and fill in the following

@ShutdownOnFailedCommand 1 //set to 0 if updating multiple servers at once
@NoPromptForPassword 1
login anonymous
app_update 244310
quit

Make it executable with chmod +x ssdk2013mp-update

This script will update the underlying Source SDK 2013 MP Dedicated Server, you may execute it by itself, but in this case we will use it for automatic updates.

Next, create a service file in /etc/systemd/system/

Example tf2classic.service:

[Unit]
Description=TF2Classic
After=network-online.target
Wants=network-online.target

[Service]
Type=forking
User=steam
WorkingDirectory=/home/tf2classic
RemainAfterExit=yes
ExecStartPre=/usr/games/steamcmd +runscript /opt/tf2classic/ssdkb2013mp-update
ExecStartPre=/opt/tf2classic/TF2CDownloaderLinux --update
ExecStart=/opt/tf2classic/server/srcds_run -console -game tf2classic +map tr_walkway_fastcat_v1 -port 27020 +maxplayers 32 +sv_setsteamaccount XXXXXXX
TimeoutStartSec=infinity
Restart=always

[Install]
WantedBy=multi-user.target

Then, enable the service to start with the init system:

# systemctl enable tf2classic.service

Next, switch to the root user using sudo su and execute crontab -e. This is where you can set cronjobs, include something like the following:

# Restart and update check for TF2Classic every day at 4 AM.

0 4 * * * systemctl restart tf2classic.service

You may create as many services as you have TF2C servers but remember to name the service files uniquely, enable them in systemctl, and add them to the crontab.

Systemd manual start, stop, restart/update

If you don't wish to use the service files above to automatically boot servers, or you need to perform these actions for maintenance: you may issue commands to manually start, stop, restart, or update the server(s) through systemd.

# systemctl restart tf2classic # in case you need to restart manually or to grab updates!! 
# systemctl stop tf2classic # in case you need to stop the server manually
# systemctl start tf2classic # in case you need to start the server manually
# systemctl disable tf2classic # in case you need to stop the server from booting as your system initializes 
# systemctl enable tf2classic # in case you need to start the server to boot as your system initializes 


See also Dedicated Linux Server Extras.