Terraria Server Installation on Linux
Terraria is a 2D sandbox game that supports dedicated multiplayer servers on Linux. This guide covers the complete installation and configuration of a TShock-powered Terraria server, which includes essential administrative tools, permission systems, and plugin support. TShock adds superior server management capabilities including player bans, regions, and extensive command support beyond the vanilla server.
Table of Contents
- System Requirements
- Installing TShock
- Server Configuration
- World Setup and Management
- Permission System
- Plugin Management
- Firewall and Port Configuration
- Running with Systemd
- Administrative Commands
- Backup and Recovery
- Monitoring
- Conclusion
System Requirements
Before starting, verify your system meets these requirements:
- Ubuntu 20.04 LTS, CentOS 7+, or compatible Linux distribution
- 2GB RAM minimum (4GB recommended for 10+ players)
- 10GB disk space
- .NET 6.0 Runtime (required for TShock)
- Root or sudo access
TShock is a .NET application, so the .NET runtime is mandatory for operation.
Installing TShock
Update system packages and install dependencies:
sudo apt-get update
sudo apt-get install -y wget curl git build-essential curl gnupg apt-transport-https ca-certificates
Install .NET 6.0 Runtime:
# Add Microsoft repository
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
# Install .NET runtime
sudo apt-get update
sudo apt-get install -y dotnet-runtime-6.0
Verify .NET installation:
dotnet --version
dotnet --info | grep -A 5 "Runtime"
Create dedicated user for TShock:
sudo useradd -m -s /bin/bash terraria
sudo -u terraria mkdir -p /home/terraria/tshock
Download latest TShock release:
cd /home/terraria/tshock
TSHOCK_VERSION=$(curl -s https://api.github.com/repos/Pryaxis/TShock/releases/latest | grep tag_name | cut -d'"' -f4)
sudo -u terraria wget "https://github.com/Pryaxis/TShock/releases/download/${TSHOCK_VERSION}/TShock-${TSHOCK_VERSION}.zip"
Extract TShock:
sudo -u terraria unzip -o "TShock-${TSHOCK_VERSION}.zip"
sudo -u terraria chmod +x /home/terraria/tshock/TShock.Server
Verify extraction:
ls -la /home/terraria/tshock/
file /home/terraria/tshock/TShock.Server
Create data directory:
sudo -u terraria mkdir -p /home/terraria/terraria-data/{worlds,logs,plugins}
Server Configuration
TShock uses config.json for server configuration. Initialize default configuration:
cd /home/terraria/tshock
sudo -u terraria /bin/bash -c 'timeout 5 dotnet TShock.Server.dll 2>&1' || true
sleep 2
This creates the default config.json. Now customize it:
sudo tee /home/terraria/tshock/config.json > /dev/null <<'EOF'
{
"InviteCode": "myworld",
"ServerPassword": "ChangeMeToSecurePassword",
"ServerPort": 7777,
"UseSSL": false,
"RestApiPort": 7878,
"ShowItemNameInRadius": true,
"RestApiEnabled": true,
"LogPath": "logs/",
"LogFormat": "%sanitizedpath% - [%time%] %level%: %message%",
"SilentKickOnMissingPassword": false,
"DisableHardmode": false,
"DisableDungeonGuardian": false,
"EnableWhitelist": false,
"OverrideTShockToServerPassword": false,
"AutoLock": false,
"AutoUnlock": false,
"AutoSave": true,
"AutoSaveInterval": 300,
"AutoSaveOnExit": true,
"NpcStreamFarAwayPlayers": false,
"StartInvPassword": "",
"RespawnSeconds": 5,
"MaxDamage": 1175,
"MaxProjDamage": 20,
"KickOnDamageThresholdBreach": false,
"TilePaintThreshold": 15,
"CombatBookValidationThreshold": 250,
"KickOnTilePaintThresholdBreach": false,
"ForceHalloween": false,
"ForceChristmas": false,
"AllowCutTiles": true,
"AllowPlacingHauntedIceTiles": true,
"AllowDecorations": true,
"AllowIce": true,
"AllowUndergroundDesertCorruption": true,
"AllowedIceBlocksCount": 9999,
"MediumcoreThreshold": 5,
"HardcoreThreshold": 10,
"AllowRegisteringAccounts": true,
"MinimumPasswordLength": 4,
"HashAlgorithm": "sha512",
"UseServerName": false,
"ServerFullNoPermission": false,
"SaveWorldOnLastPlayerExit": true,
"BCryptWorkFactor": 7,
"ServerSidedCharacter": false,
"MediumcoreBanning": false,
"HardcoreBanning": false,
"DisableLoginBeforeJoin": false,
"DisableUUIDLogin": false,
"KickProxyUsers": true,
"DisableSpewLogs": false,
"MaxHP": 500,
"MaxMP": 250,
"EnableTokenEndpointAuthentication": false
}
EOF
sudo chown terraria:terraria /home/terraria/tshock/config.json
sudo chmod 600 /home/terraria/tshock/config.json
World Setup and Management
Create startup script for world selection and server launch:
sudo tee /home/terraria/tshock/start_server.sh > /dev/null <<'EOF'
#!/bin/bash
TSHOCK_DIR="/home/terraria/tshock"
DATA_DIR="/home/terraria/terraria-data"
WORLD_PATH="${WORLD_PATH:-$DATA_DIR/worlds/Terraria}"
DIFFICULTY="${DIFFICULTY:-normal}"
cd "$TSHOCK_DIR"
# Create world if it doesn't exist
if [ ! -f "${WORLD_PATH}.wld" ]; then
echo "Creating new world: $WORLD_PATH"
mkdir -p "$(dirname $WORLD_PATH)"
fi
export TSHOCK_WORLD_PATH="$WORLD_PATH"
export TSHOCK_LOG_PATH="$DATA_DIR/logs/"
mkdir -p "$DATA_DIR/logs"
mkdir -p "$DATA_DIR/worlds"
exec dotnet TShock.Server.dll \
-world "$WORLD_PATH" \
-difficulty "$DIFFICULTY" \
-logfile "$DATA_DIR/logs/tshock.log" \
2>&1
EOF
sudo chmod +x /home/terraria/tshock/start_server.sh
sudo chown terraria:terraria /home/terraria/tshock/start_server.sh
Test server startup:
sudo -u terraria timeout 10 bash -c 'WORLD_PATH="/home/terraria/terraria-data/worlds/TestWorld" /home/terraria/tshock/start_server.sh' || true
Check logs:
tail -20 /home/terraria/terraria-data/logs/tshock.log
Permission System
TShock uses a robust permission system. Configure user groups and permissions:
sudo tee /home/terraria/tshock/sscconfig.json > /dev/null <<'EOF'
{
"Settings": {
"Enabled": true,
"MaxDamage": 1175,
"MaxProjectileDamage": 20,
"MaxHP": 500,
"MaxMP": 250,
"KickOnDamageThresholdBreach": false,
"IgnorePvpFlag": false,
"IgnoreSSC": false,
"LogBans": true
}
}
EOF
sudo chown terraria:terraria /home/terraria/tshock/sscconfig.json
Create user groups configuration:
sudo tee /home/terraria/tshock/groups.json > /dev/null <<'EOF'
[
{
"Name": "default",
"Parent": null,
"Permissions": [
"tshock.world.read",
"tshock.npc.spawn.boss"
]
},
{
"Name": "vip",
"Parent": "default",
"Permissions": [
"tshock.world.build",
"tshock.npc.spawnheal"
]
},
{
"Name": "admin",
"Parent": null,
"Permissions": [
"*"
]
},
{
"Name": "moderator",
"Parent": "default",
"Permissions": [
"tshock.kick.self",
"tshock.ban.self",
"tshock.mute.self",
"tshock.whisper",
"tshock.admin"
]
}
]
EOF
sudo chown terraria:terraria /home/terraria/tshock/groups.json
Plugin Management
Install essential TShock plugins for enhanced functionality:
mkdir -p /home/terraria/tshock/ServerPlugins
cd /home/terraria/tshock/ServerPlugins
# Download useful plugins from TShock community
# Example: BossPresence plugin
sudo -u terraria wget https://github.com/tylerjwatson/BossPresence/releases/download/latest/BossPresence.dll
# Example: AntiCheat plugin
sudo -u terraria wget https://github.com/Pryaxis/TShock/releases/download/AntiCheat/AntiCheat.dll
# Verify plugin installation
ls -la /home/terraria/tshock/ServerPlugins/
Create plugin configuration directory:
sudo -u terraria mkdir -p /home/terraria/tshock/ServerPlugins/
ls -la /home/terraria/tshock/ServerPlugins/
Firewall and Port Configuration
TShock uses TCP for server communication. Default port is 7777, with optional REST API on 7878.
Configure UFW firewall:
sudo ufw allow 7777/tcp
sudo ufw allow 7878/tcp
sudo ufw status numbered
For iptables-based systems:
sudo iptables -A INPUT -p tcp --dport 7777 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 7878 -j ACCEPT
sudo iptables-save | sudo tee /etc/iptables/rules.v4
Verify port binding:
sudo netstat -tlnp | grep dotnet
ss -tlnp | grep 7777
Port forwarding on a router may be required for remote connections.
Running with Systemd
Create systemd service for automatic startup and management:
sudo tee /etc/systemd/system/tshock.service > /dev/null <<'EOF'
[Unit]
Description=TShock Terraria Server
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=terraria
Group=terraria
WorkingDirectory=/home/terraria/tshock
EnvironmentFile=/home/terraria/tshock/server.env
ExecStart=/home/terraria/tshock/start_server.sh
Restart=on-failure
RestartSec=15
StandardOutput=journal
StandardError=journal
# Resource limits
LimitNOFILE=65536
LimitNPROC=4096
# Security
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/home/terraria/terraria-data
[Install]
WantedBy=multi-user.target
EOF
Create environment file:
sudo tee /home/terraria/tshock/server.env > /dev/null <<'EOF'
WORLD_PATH=/home/terraria/terraria-data/worlds/Terraria
DIFFICULTY=normal
EOF
sudo chown terraria:terraria /home/terraria/tshock/server.env
sudo chmod 600 /home/terraria/tshock/server.env
Enable and start service:
sudo systemctl daemon-reload
sudo systemctl enable tshock.service
sudo systemctl start tshock.service
sudo systemctl status tshock.service
Monitor service logs:
sudo journalctl -u tshock.service -f
sudo journalctl -u tshock.service -n 50 --no-pager
Administrative Commands
Once the server is running, use these commands in-game or via console:
List connected players:
# In-game as admin: /users
# Via REST API:
curl http://localhost:7878/v3/players
Ban a player:
# In-game:
# /ban username reason
# /banuserid userid reason
# /ipban ipaddress reason
# Via console:
curl -X POST http://localhost:7878/v3/bans \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"username":"playerName"}'
Kick a player:
# In-game:
# /kick username reason
Manage world settings:
# In-game:
# /hardmode - Toggle hardmode
# /dungeon - Teleport to dungeon
# /tpnpc npcname - Teleport NPC
Broadcast messages:
# In-game:
# /say message
# /announce message
Reload configuration:
# In-game as admin:
# /reload
Backup and Recovery
Create automated backup script:
sudo tee /home/terraria/backup_tshock.sh > /dev/null <<'EOF'
#!/bin/bash
DATA_DIR="/home/terraria/terraria-data"
BACKUP_DIR="$DATA_DIR/backups"
RETENTION_DAYS=30
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"
# Backup worlds and database
tar -czf "$BACKUP_DIR/tshock_backup_${TIMESTAMP}.tar.gz" \
-C "$DATA_DIR" worlds/ \
2>/dev/null
if [ $? -eq 0 ]; then
echo "[$(date)] Backup created successfully"
else
echo "[$(date)] Backup failed!" >&2
exit 1
fi
# Cleanup old backups
find "$BACKUP_DIR" -name "tshock_backup_*.tar.gz" -mtime +${RETENTION_DAYS} -delete
echo "[$(date)] Cleanup complete (retention: ${RETENTION_DAYS} days)"
EOF
sudo chmod +x /home/terraria/backup_tshock.sh
sudo chown terraria:terraria /home/terraria/backup_tshock.sh
Add to crontab:
sudo tee -a /var/spool/cron/crontabs/terraria > /dev/null <<'EOF'
0 2 * * * /home/terraria/backup_tshock.sh >> /home/terraria/terraria-data/logs/backup.log 2>&1
EOF
sudo systemctl restart cron
Restore from backup:
# Stop server
sudo systemctl stop tshock.service
# Restore backup
BACKUP_FILE="/home/terraria/terraria-data/backups/tshock_backup_20240101_020000.tar.gz"
sudo -u terraria tar -xzf "$BACKUP_FILE" -C /home/terraria/terraria-data/
# Start server
sudo systemctl start tshock.service
Monitoring
Create monitoring script:
sudo tee /home/terraria/check_tshock.sh > /dev/null <<'EOF'
#!/bin/bash
# Check if service is running
if sudo systemctl is-active --quiet tshock.service; then
echo "✓ TShock service is running"
else
echo "✗ TShock service is NOT running"
exit 1
fi
# Check port
if sudo netstat -tlnp 2>/dev/null | grep -q 7777; then
echo "✓ Server listening on port 7777"
else
echo "✗ Server NOT listening"
exit 1
fi
# Get player count from REST API
PLAYER_COUNT=$(curl -s http://localhost:7878/v3/players 2>/dev/null | grep -o '"' | wc -l)
echo "Connected players (API check): ~$((PLAYER_COUNT/4))"
# Check recent errors
ERRORS=$(tail -20 /home/terraria/terraria-data/logs/tshock.log 2>/dev/null | grep -i "error\|exception" | wc -l)
echo "Recent errors: $ERRORS"
# Disk usage
USAGE=$(df -h /home/terraria/terraria-data | awk 'NR==2 {print $5}')
echo "Disk usage: $USAGE"
EOF
sudo chmod +x /home/terraria/check_tshock.sh
Update TShock to latest version:
sudo systemctl stop tshock.service
cd /home/terraria/tshock
LATEST_VERSION=$(curl -s https://api.github.com/repos/Pryaxis/TShock/releases/latest | grep tag_name | cut -d'"' -f4)
sudo -u terraria wget "https://github.com/Pryaxis/TShock/releases/download/${LATEST_VERSION}/TShock-${LATEST_VERSION}.zip"
sudo -u terraria unzip -o "TShock-${LATEST_VERSION}.zip"
sudo systemctl start tshock.service
Conclusion
Your TShock Terraria server is now fully configured with proper user management, permission systems, and automated backups. This setup provides a professional multiplayer experience with advanced administrative controls.
Key takeaways:
- Always use a secure server password
- Configure permissions groups for different player types
- Implement regular automated backups
- Monitor server logs for issues and updates
- Use plugins carefully to enhance functionality without compromising stability
- Keep server and plugins updated regularly
A well-managed TShock server can support multiple players with excellent stability and administrative control for many years.


