Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

User:Webb/New linux server: Difference between revisions

From TF2 Classified Wiki
Webb (talk | contribs)
No edit summary
Webb (talk | contribs)
No edit summary
 
(16 intermediate revisions by the same user not shown)
Line 1: Line 1:
:''This is a WIP updated version of the Linux dedicated server article. I want to ask for feedback before moving out of my user namespace. The original 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/''
:''This article is based on a guide written by Raizo, the original of which can be found [https://blog.raizo.dev/posts/tf2-classic-linux-server-tutorial/ here].''


== Prerequisites ==
== Reading this article ==
 
* A Linux server running Ubuntu Server<sup>*</sup> on an x86_64 CPU<sup>**</sup> with root/administrator access
* A SFTP/SSH client (PuTTY, Termius, FileZilla, MobaXterm)
* At least 20GB of free storage
* A minimum of a 10Mbps upload speed if you intend on hosting a server over the Internet. More bandwidth may be needed if custom maps are used.
 
<sup>*</sup> This guide was written for and tested on Ubuntu Server 24.04 LTS Minimal. Other distros may use different package names and conventions.
 
<sup>**</sup> Using an x86 compatibility layer like Box86 for another architecture is unsupported and may not work.
 
=== 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 -->
A command prefixed by <code>#</code> is meant to be run as '''root'''.
A command prefixed by <code>#</code> is meant to be run as '''root'''.
Line 18: Line 7:
A command prefixed by <code>$</code> is meant to be run as a '''regular user''' without root permissions. In this case the <code>srcds</code> user.
A command prefixed by <code>$</code> is meant to be run as a '''regular user''' without root permissions. In this case the <code>srcds</code> user.


SteamCMD shell commands will use the <code>Steam></code> prefix.
A command prefixed by <code>Steam></code> is meant to be run inside of a SteamCMD shell.


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 user for SteamCMD and Source SDK Base 2013 Dedicated Server ===
== Prerequisites ==
 
* A Linux server running Ubuntu Server<sup>*</sup> on an x86_64 CPU<sup>**</sup> with root access
* At least 20GB of free storage
* A minimum of a 10Mbps upload speed if you intend on hosting a server over the Internet, more will be needed if you host custom content
* An opened port on your firewall for the server
* ''Optional'': An SSH/SFTP client if doing remote access/file management
* ''Optional'': A port that's been forwarded for the server if you wish to have it accessible over the internet


Pick a directory to install your server into. Many put it under a directory in <code>/opt</code>, but for this guide we'll be using <code>/home/srcds</code>.
<sup>*</sup> This guide was written for and tested on Ubuntu Server 24.04 LTS Minimal. Other distros may use different package names and conventions.


Create a disabled user with a home directory:
<sup>**</sup> Using an x86 compatibility layer like Box86 for another architecture is unsupported and may not work.


<pre>
== Preparing for install ==
# useradd -s /bin/false -mr srcds
</pre>


<code>-m</code> creates a home directory for the new user, <code>-r</code> specifies that it's a system account that will not have a password, and <code>-s /bin/false</code> prevents the account from having a default shell.
=== Dependencies ===


=== Installing Source SDK Base 2013 Dedicated Server (srcds), SteamCMD, and dependencies ===
We'll need to install some required packages and tools for our server to work, as well as for installation.


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.
Since the legacy TF2C branch, Source SDK, and SteamCMD are built for 32-bit, we'll need to enable 32-bit packages. We'll also add the <code>multiverse</code> repository which has SteamCMD.


<pre>
<pre>
Line 44: Line 38:
</pre>
</pre>


Install SteamCMD, and miscellaneous packages that we'll be using.
Next, we'll install the <code>dialog</code> package so the Steam Subscriber Agreement dialog works, and then the rest of the packages we need.


webbnote: libcurl4-gnutls-dev broken
<pre>
<pre>
# apt install dialog
# apt install dialog
# apt install steamcmd p7zip aria2 tilde lib32z1 libbz2-1.0:i386 lib32gcc-s1 lib32stdc++6 libcurl3-gnutls:i386 libsdl2-2.0-0:i386 libcurl4-gnutls-dev libcurl4-gnutls-dev:i386 wget
# apt install steamcmd p7zip aria2 tilde lib32z1 libbz2-1.0:i386 lib32gcc-s1 lib32stdc++6 libcurl3-gnutls:i386 libsdl2-2.0-0:i386 wget
</pre>
</pre>
''<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.
''


Log out of your current session, and relogin. Switch to the srcds user you created:
If your version of Ubuntu doesn't come with a text editor, you may install one now. For this guide we'll use <code>nano</code>.
 
<pre># apt install nano</pre>
 
=== Creating a user for the server ===
 
Pick a directory to install your server into. Many put it under a directory in <code>/opt</code>, but for this guide we'll be using <code>/home/srcds</code>.
 
Create a disabled user with a home directory.
 
<pre>
# useradd -s /bin/false -mr srcds
</pre>
 
<code>-m</code> creates a home directory for the new user, <code>-r</code> specifies that it's a system account that will not have a password, and <code>-s /bin/false</code> prevents the account from having a default shell.  
 
=== Installing Source SDK Base 2013 Dedicated Server (SDK 2013) ===
 
Switch to the new <code>srcds</code> user you made, and run SteamCMD.


<pre>
<pre>
Line 63: Line 72:
</pre>
</pre>


You should be dropped into a SteamCMD shell. We can install the SDK now. Note that force_install_dir must be ran before login anonymous.
You should be dropped into a SteamCMD shell. We can install the SDK 2013 now. Note that <code>force_install_dir</code> must be ran before <code>login anonymous</code>.


<pre>
<pre>
Line 72: Line 81:
</pre>
</pre>


If everything went well, srcds itself should be installed and you should be back at your user shell.
If everything went well, <code>srcds</code> should be installed and you should be back at your user shell.
 
Before we continue we'll need to fix some files.
== Downloading TF2 Classic ==
 
We'll be downloading the archived verison of TF2C. You can also use the TF2CDownloader if you wish.
 
<pre>
$ wget https://wiki.tf2classic.com/archive/tf2classic-2.2.3.zip -O /tmp/tf2classic.zip
$ mkdir ~/sdk/tf2classic
$ cd ~/sdk/tf2classic
$ 7z x /tmp/tf2classic.zip && rm /tmp/tf2classic.zip
</pre>


This will downloaded the latest archive of TF2C, create its directory, and extract it. If everything succeeds it will delete tf2classic.zip.
Valve changed some shared object file names in the SDK, but the objects included with our install of SDK 2013 have not adopted the new names.
Since these are simply renames, we can symlink them.  


=== 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.'''
'''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>
<pre>
Line 111: Line 101:
$ ln -s vphysics_srv.so vphysics.so
$ ln -s vphysics_srv.so vphysics.so
$ ln -s soundemittersystem_srv.so soundemittersystem.so
$ ln -s soundemittersystem_srv.so soundemittersystem.so
$ cd ~/sdk/tf2classic/bin
$ ln -s server.so server_srv.so
</pre>
</pre>


We can also fix steamclient.so errors by symlinking a file to .steam.
Finally, we'll also symlink <code>steamclient.so</code> to a special directory to prevent bugs.


<pre>
<pre>
Line 122: Line 110:
</pre>
</pre>


=== Testing the server ===
== Installing TF2C ==


Before proceeding, we can test the server to make sure the install works.
We'll be downloading the archived verison of TF2C, since it's unlikely to get updates. You have the option of using TF2CDownloader, but we won't cover it here.


<pre>
<pre>
$ cd ~/sdk
$ wget https://wiki.tf2classic.com/kachemak/tf2classic.zip -O /tmp/tf2classic.zip
$ ./srcds_run -game tf2classic +map ctf_2fort +sv_password changethis
$ mkdir ~/sdk/tf2classic
$ cd ~/sdk/tf2classic
$ 7z x /tmp/tf2classic.zip && rm /tmp/tf2classic.zip
</pre>
</pre>


If all goes well, it should launch and be joinable.
This will download the latest archive, create its directory, and extract it. If extraction succeeds it will also delete the downloaded archive.
 
We'll also need to do a quick symlink in TF2C's bin folder.
 
<pre>
$ cd ~/sdk/tf2classic/bin
$ ln -s server.so server_srv.so
</pre>


=== Server Configuration ===
== Testing the server ==


Generate your server config(s) on [https://cfg.tf/ cfg.tf].
Before proceeding, we can manually run the server to make sure the install was successful.


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).
<pre>
$ cd ~/sdk
$ ./srcds_run -game tf2classic +map ctf_2fort +sv_password changethis
</pre>


Upload the generated ZIP file to your server using SFTP, unzip the folder using:
If all goes well, it should start.


<pre>unzip <archive>.zip</pre>
== Server Configuration ==


And merge the <code>cfg</code> folder with <code>/home/srcds/sdk/tf2classic/cfg/</code>.
For a basic, private server, you should only need to set a password in <code>sdk/tf2classic/cfg/server.cfg</code> by appending the file with <code>sv_password yourpassword</code>.
You can also make it LAN-only by appending <code>sv_lan 1</code> in the same file.


== Running the server ==
If you want a more complicated setup, consider using [https://cfg.tf/ cfg.tf]. If you don't need this you can skip to the next section.


=== Creating the server script ===
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).


Change into the server directory with:
Upload the generated ZIP file to your server, perhaps using SFTP, and unzip the folder.


<pre>$ cd /opt/tf2classic/server/</pre>
<pre>
$ cd /tmp
$ unzip $PATH_TO_ARCHIVE</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 nano. Run:
And merge the <code>cfg</code> folder with <code>/home/srcds/sdk/tf2classic/cfg/</code>.


<pre>$ nano runserver.sh</pre>
<pre>
$ rsync /tmp/cfg ~/srcds/sdk/tf2classic/cfg
$ rm -rf /tmp/cfg
</pre>


Fill it with this line (you may be able to paste using <code>Shift+Insert</code>):
== Managing the server via Systemd ==


<pre>./srcds_run -console -game tf2classic +map pl_upward +maxplayers 24</pre>
Systemd is a program that will automatically handle things like logging, restarts, and starting your server when your machine boots. We'll use this to run our server, instead of manually running commands.


Feel free to change the map and maxplayers. There are more arguments, but we’ll keep it basic.
=== Creating an SDK 2013 update script ===


Save the file by clicking <code>CRTL+X</code>, and then <code>Y</code> to write your changes.
We're going to create a script that will update SDK 2013 for us instead of typing it out manually each time. Later, we'll optionally use this script to check and update SDK 2013 on our server automatically when the server starts.  


Now, make the script executable with:
First, let's create a directory for the script.


<pre>
<pre>
$ chmod +x runserver.sh
$ mkdir ~/bin
$ nano ~/bin/update-sdk.steamcmd
</pre>
</pre>


Finally, all you need to do to start the server is run <code>./runserver.sh</code>!
Fill the file with the following contents:


If you want it to run even after closing the terminal window, run <code>nohup ./runserver.sh &</code> followed by <code>disown</code>
=== 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 <code>ssdk2013mp-update</code> and fill in the following
<pre>
<pre>
@ShutdownOnFailedCommand 1 //set to 0 if updating multiple servers at once
@ShutdownOnFailedCommand 1 //set to 0 if updating multiple servers at once
@NoPromptForPassword 1
@NoPromptForPassword 1
force_install_dir /home/srcds/sdk
login anonymous
login anonymous
app_update 244310 -beta previous2021
app_update 244310 -beta previous2021
Line 187: Line 189:
</pre>
</pre>


Make it executable with <code>chmod +x ssdk2013mp-update</code>
You can execute this script manually by using the +runscript argument on SteamCMD.


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.  
<pre>
$ . /etc/environment
$ steamcmd +runscript /home/srcds/bin/update-sdk.steamcmd
</pre>


Next, create a service file in <code>/etc/systemd/system/</code>
=== Creating a service file ===
 
Create a service file in <code>/etc/systemd/system/</code> as root. For this guide we'll use <code>/etc/systemd/system/tf2c.service</code>.


Example <code>tf2classic.service</code>:
<pre>
<pre>
[Unit]
[Unit]
Description=TF2Classic
Description=TF2C Server
After=network-online.target
After=network-online.target
Wants=network-online.target
Wants=network-online.target


[Service]
[Service]
Type=forking
Type=simple
User=steam
User=srcds
WorkingDirectory=/home/tf2classic
StandardError=journal
RemainAfterExit=yes
StandardOutput=journal
ExecStartPre=/usr/games/steamcmd +runscript /opt/tf2classic/ssdkb2013mp-update
WorkingDirectory=/home/srcds/sdk
ExecStartPre=/opt/tf2classic/TF2CDownloaderLinux --update
RemainAfterExit=no
ExecStart=/opt/tf2classic/server/srcds_run -console -game tf2classic +map tr_walkway_fastcat_v1 -port 27020 +maxplayers 32 +sv_setsteamaccount XXXXXXX
ExecStartPre=/usr/games/steamcmd +runscript /home/srcds/bin/update-sdk.steamcmd # Exclude or comment this if you don't want to check for an update on each restart
Environment="LD_LIBRARY_PATH=".:bin:$LD_LIBRARY_PATH""
ExecStart=/usr/bin/script -e -c "/home/srcds/sdk/srcds_linux +map ctf_2fort -game tf2classic +maxplayers 24" /dev/null
TimeoutStartSec=infinity
TimeoutStartSec=infinity
Restart=always
Restart=always
Line 215: Line 223:
</pre>
</pre>


Then, enable the service to start with the init system:
Then, enable the service to start with Systemd on boot.
 
<pre>
<pre>
# systemctl enable tf2classic.service
# systemctl enable tf2c.service
</pre>
</pre>


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:
You may create as many services as you have TF2C servers but remember to name the service files uniquely. When modifying service files, remember to run <code>systemctl daemon-reload</code> before restarting the service.
 
=== Automatic restarts using crontab ===
 
Cron is a program built into most Linux distros that runs scheduled commands.
 
As root, execute <code>crontab -e</code>. This will open a special file in your editor where you can declare what jobs you want to run and when. Let's add a job to run at 04:00 that will restart our server.


<pre>
<pre>
# Restart and update check for TF2Classic every day at 4 AM.
0 4 * * * systemctl restart tf2c.service
 
0 4 * * * systemctl restart tf2classic.service
</pre>
</pre>


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>.
=== Manually managing services ===
 
=== 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.  
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.  


<pre>
<pre>
# systemctl restart tf2classic # in case you need to restart manually or to grab updates!!  
# systemctl restart tf2c # in case you need to restart manually or to grab updates!!  
# systemctl stop tf2classic # in case you need to stop the server manually
# systemctl stop tf2c # in case you need to stop the server manually
# systemctl start tf2classic # in case you need to start the server manually
# systemctl start tf2c # 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 disable tf2c # 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  
# systemctl enable tf2c # in case you need to start the server to boot as your system initializes  
</pre>
</pre>


''</br>See also [[Dedicated_Linux_server_extras|Dedicated Linux Server Extras]].''
''</br>See also [[Dedicated_Linux_server_extras|Dedicated Linux Server Extras]].''
[[Category:Guides]]
[[Category:Guides]]