Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
.DS_Store
# macOS
.DS_Store

# IDE
.idea/
.vscode/
*.swp
*.swo

# Docker
*.log
16 changes: 10 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
## Pull our base image
FROM debian:12-slim
FROM debian:13-slim

## Image Information
LABEL maintainer="Jeff Nelson <jeff@netwar.org>"
ARG DEBIAN_FRONTEND=noninteractive

## Set Build Arguments
ENV APP_DIR="/app" \

Check warning on line 9 in Dockerfile

View workflow job for this annotation

GitHub Actions / deploy / build-and-publish

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "STEAMCMD_AUTH_CODE") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/

Check warning on line 9 in Dockerfile

View workflow job for this annotation

GitHub Actions / deploy / build-and-publish

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "STEAMCMD_PASSWORD") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
GAME_DIR="/app/tf2" \
GAME_USER="steam" \
STEAMCMD_APP="232250" \
Expand All @@ -21,14 +21,14 @@
&& apt install -y \
curl \
lib32gcc-s1 \
lib32ncurses5-dev \
lib32ncurses-dev \
lib32stdc++6 \
lib32z1 \
libc6 \
libcurl3-gnutls:i386 \
libncurses5 \
libcurl3t64-gnutls:i386 \
libncurses6 \
libsdl2-2.0-0 \
libtinfo5 \
libtinfo6 \
unzip \
zlib1g \
&& apt clean \
Expand All @@ -49,7 +49,7 @@
USER $GAME_USER

## Download SteamCMD
RUN curl -s http://media.steampowered.com/installer/steamcmd_linux.tar.gz | tar -xzC $STEAMCMD_DIR \
RUN curl -s https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar -xzC $STEAMCMD_DIR \
&& $STEAMCMD_DIR/steamcmd.sh \
+login $STEAMCMD_USER $STEAMCMD_PASSWORD $STEAMCMD_AUTH_CODE \
+quit \
Expand All @@ -65,5 +65,9 @@
## Set working directory
WORKDIR $APP_DIR

## Health check to monitor srcds process
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
CMD pgrep -f srcds_linux || exit 1

## Start the run script
CMD ["bash", "run.sh"]
5 changes: 3 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/usr/bin/env bash
#!/bin/bash
set -e

docker build -t netwarlan/tf2 .
docker build -t ghcr.io/netwarlan/tf2 "$@" .
41 changes: 35 additions & 6 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# Team Fortress 2


[![Docker Build](https://img.shields.io/github/actions/workflow/status/netwarlan/tf2/build.yml?label=build)](https://github.com/netwarlan/tf2/actions)
[![License](https://img.shields.io/github/license/netwarlan/tf2)](LICENSE)

The following repository contains the source files for building a Team Fortress 2 server.

## Running

### Running
To run the container, issue the following example command:
```
docker run -d \
Expand All @@ -14,7 +17,8 @@ docker run -d \
ghcr.io/netwarlan/tf2
```

### Environment Variables
## Environment Variables

We can make dynamic changes to our TF2 containers by adjusting some of the environment variables passed to our image.
Below are the ones currently supported and their (defaults):

Expand All @@ -33,8 +37,33 @@ TF2_SERVER_REMOTE_CFG | No url set
TF2_SERVER_ENABLE_PROPHUNT | false
TF2_SERVER_CONFIG | server.cfg

## Health Check

### Prop Hunt Setup
A prop hunt server can be stood up by passing the following environment variable `TF2_SERVER_PROPHUNT=true` when starting up the container.
The container includes a built-in health check that monitors the srcds process. Docker will automatically report the container as unhealthy if the game server stops running.

## Prop Hunt Setup

A prop hunt server can be stood up by passing the following environment variable `TF2_SERVER_ENABLE_PROPHUNT=true` when starting up the container.
This will install MetaMod and SourceMod into the container as well as all the necessary assets like maps, sounds, sourcemod plugins, etc...
*Note: It does appear the TF2 server crashes when attempting to connect to the server for the first time after standing up this type of server. Appears to be a bug, but simply connecting again appears to work fine. No further testing has been done.

*Note: It does appear the TF2 server crashes when attempting to connect to the server for the first time after standing up this type of server. Appears to be a bug, but simply connecting again appears to work fine. No further testing has been done.*

## Troubleshooting

**Server won't start**
- Check Docker logs: `docker logs <container_id>`
- Verify all required ports are available and not in use
- Ensure adequate disk space for game files

**Slow startup**
- First startup downloads ~8GB of game files
- Subsequent startups are faster if game files are persisted via volume

**Players can't connect**
- Verify ports 27015 UDP/TCP are forwarded/exposed correctly
- Check `TF2_SVLAN` is set to `0` for internet play
- Ensure firewall rules allow incoming connections

## License

This project is open source. See the repository for license details.
39 changes: 26 additions & 13 deletions run.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
set -e

echo "

Expand All @@ -23,18 +24,29 @@ echo "

## Set default values if none were provided
## ==============================================
[[ -z "$TF2_SERVER_PORT" ]] && TF2_SERVER_PORT="27015"
[[ -z "$TF2_SERVER_MAXPLAYERS" ]] && TF2_SERVER_MAXPLAYERS="24"
[[ -z "$TF2_SERVER_MAP" ]] && TF2_SERVER_MAP="ctf_2fort"
[[ -z "$TF2_SVLAN" ]] && TF2_SVLAN="0"
[[ -z "$TF2_SERVER_HOSTNAME" ]] && TF2_SERVER_HOSTNAME="TF2 Server"
[[ ! -z "$TF2_SERVER_PW" ]] && TF2_SERVER_PW="sv_password $TF2_SERVER_PW"
[[ ! -z "$TF2_SERVER_RCONPW" ]] && TF2_SERVER_RCONPW="rcon_password $TF2_SERVER_RCONPW"
[[ -z "$TF2_SERVER_REMOTE_CFG" ]] && TF2_SERVER_REMOTE_CFG=""
[[ -z "$TF2_SERVER_UPDATE_ON_START" ]] && TF2_SERVER_UPDATE_ON_START=true
[[ -z "$TF2_SERVER_VALIDATE_ON_START" ]] && TF2_SERVER_VALIDATE_ON_START=false
[[ -z "$TF2_SERVER_ENABLE_PROPHUNT" ]] && TF2_SERVER_ENABLE_PROPHUNT=false
[[ -z "$TF2_SERVER_CONFIG" ]] && TF2_SERVER_CONFIG="server.cfg"
TF2_SERVER_PORT="${TF2_SERVER_PORT:-27015}"
TF2_SERVER_MAXPLAYERS="${TF2_SERVER_MAXPLAYERS:-24}"
TF2_SERVER_MAP="${TF2_SERVER_MAP:-ctf_2fort}"
TF2_SVLAN="${TF2_SVLAN:-0}"
TF2_SERVER_HOSTNAME="${TF2_SERVER_HOSTNAME:-TF2 Server}"
[[ -n "$TF2_SERVER_PW" ]] && TF2_SERVER_PW="sv_password $TF2_SERVER_PW"
[[ -n "$TF2_SERVER_RCONPW" ]] && TF2_SERVER_RCONPW="rcon_password $TF2_SERVER_RCONPW"
TF2_SERVER_REMOTE_CFG="${TF2_SERVER_REMOTE_CFG:-}"
TF2_SERVER_UPDATE_ON_START="${TF2_SERVER_UPDATE_ON_START:-true}"
TF2_SERVER_VALIDATE_ON_START="${TF2_SERVER_VALIDATE_ON_START:-false}"
TF2_SERVER_ENABLE_PROPHUNT="${TF2_SERVER_ENABLE_PROPHUNT:-false}"
TF2_SERVER_CONFIG="${TF2_SERVER_CONFIG:-server.cfg}"

## Validate numeric inputs
## ==============================================
if [[ ! "$TF2_SERVER_PORT" =~ ^[0-9]+$ ]]; then
echo "Error: TF2_SERVER_PORT must be a valid number"
exit 1
fi
if [[ ! "$TF2_SERVER_MAXPLAYERS" =~ ^[0-9]+$ ]]; then
echo "Error: TF2_SERVER_MAXPLAYERS must be a valid number"
exit 1
fi



Expand Down Expand Up @@ -81,7 +93,7 @@ EOF

## Download config if needed
## ==============================================
if [[ ! -z "$TF2_SERVER_REMOTE_CFG" ]]; then
if [[ -n "$TF2_SERVER_REMOTE_CFG" ]]; then
echo "
╔═══════════════════════════════════════════════╗
║ Downloading remote config ║
Expand Down Expand Up @@ -124,6 +136,7 @@ curl -s ${SOURCEMOD_BASE_URL}/${SOURCEMOD_LATEST} | tar -xzC $GAME_DIR/tf
echo "Installing PropHunt Plugins"
curl -s ${TF2ITEMS_BUILD_URL} --output /tmp/items.zip
unzip -qq -o /tmp/items.zip -d $GAME_DIR/tf
rm -f /tmp/items.zip

echo "Installing Maps/Sounds/Configs"
mkdir /tmp/prophunt-data
Expand Down