Factorio Headless Server on Linux

Factorio is a factory-building game que soporta cooperative multiplayer through servidor dedicados. Esta guía cubre downloading Factorio server software, configuring server-settings.json for gameplay parameters, setting up map generation with custom seeds, installing mods, enabling RCON for remote console access, and managing the server with systemd. Factorio servers are lightweight and efficient, making them ideal for long-running multiplayer factories.

Tabla de contenidos

Requisitos del sistema

Factorio is lightweight compared to other multiplayer games:

  • Ubuntu 20.04 LTS or later
  • 2GB RAM minimum (4GB recommended for 50+ players)
  • 10GB disk space
  • Single CPU core minimum (dual-core recommended)
  • Stable internet connection
  • Factorio game license (can use trial)

Factorio runs efficiently even on modest hardware, making it excellent for shared hosting.

Descargaing Factorio Server

Factorio server is available directly from the publisher. First, register for a player account:

  1. Visit https://www.factorio.com/
  2. Crea unn account and register your copy
  3. Go to https://www.factorio.com/download and note your download URL

Create dedicated factorio user:

sudo useradd -m -s /bin/bash factorio
sudo -u factorio mkdir -p /home/factorio/factorio-server

Descarga Factorio server (replace VERSION with current version):

cd /home/factorio/factorio-server

# Download latest version (requires authentication)
sudo -u factorio wget --user your_username --password your_password \
    https://factorio.com/get-download/stable/headless/linux64 \
    -O factorio_headless_x64.tar.xz

# Alternative: use curl with auth
sudo -u factorio curl -L "https://factorio.com/get-download/stable/headless/linux64" \
    --user your_username:your_password \
    -o factorio_headless_x64.tar.xz

Extrae the server:

sudo -u factorio tar -xf factorio_headless_x64.tar.xz
ls -la /home/factorio/factorio-server/factorio/bin/x64/

Verifica la instalación:

/home/factorio/factorio-server/factorio/bin/x64/factorio --version

Create data directories:

sudo -u factorio mkdir -p /home/factorio/factorio-data/{saves,mods,scenarios,logs}

Server Configuration

Crea el main startup script:

sudo tee /home/factorio/factorio-server/start_server.sh > /dev/null <<'EOF'
#!/bin/bash

FACTORIO_DIR="/home/factorio/factorio-server/factorio"
DATA_DIR="/home/factorio/factorio-data"
SAVE_NAME="${SAVE_NAME:-factorio_saves}"
ADMIN_PASSWORD="${ADMIN_PASSWORD:-changeme}"
GAME_PASSWORD="${GAME_PASSWORD:-}"

cd "$DATA_DIR"

mkdir -p "$DATA_DIR/saves"
mkdir -p "$DATA_DIR/logs"

# Create world if it doesn't exist
if [ ! -f "$DATA_DIR/saves/$SAVE_NAME.zip" ]; then
    echo "Creating new world: $SAVE_NAME"
    "$FACTORIO_DIR/bin/x64/factorio" \
        --create "$DATA_DIR/saves/$SAVE_NAME.zip" \
        --map-gen-seed 12345
fi

# Run the server
exec "$FACTORIO_DIR/bin/x64/factorio" \
    --start-server "$DATA_DIR/saves/$SAVE_NAME.zip" \
    --server-settings "$DATA_DIR/server-settings.json" \
    --server-whitelist "$DATA_DIR/whitelist.json" \
    --console-log "$DATA_DIR/logs/factorio_$(date +%Y%m%d).log" \
    2>&1
EOF

sudo chmod +x /home/factorio/factorio-server/start_server.sh
sudo chown factorio:factorio /home/factorio/factorio-server/start_server.sh

Server Settings JSON

Create comprehensive server configuration:

sudo tee /home/factorio/factorio-data/server-settings.json > /dev/null <<'EOF'
{
  "name": "My Factorio Server",
  "description": "Cooperative factory building server",
  "tags": ["factorio", "coop", "factory"],
  "max_players": 255,
  "visibility": {
    "public": true,
    "lan": false
  },
  "token": "",
  "game_password": "",
  "require_user_verification": true,
  "max_upload_in_kilobytes_per_second": 0,
  "minimum_latency_in_ticks": 0,
  "ignore_player_limit_for_returning_players": false,
  "allow_commands": "admins-only",
  "pause_when_empty": false,
  "only_admins_can_pause_the_game": true,
  "only_admins_can_manage_players": false,
  "autosave_interval": 10,
  "autosave_slots": 5,
  "afk_autokick_interval": 0,
  "auto_pause": true,
  "only_admins_can_trigger_incidents": true,
  "admins": [
    "YOUR_USERNAME"
  ],
  "ban_list_file": "ban-list.json",
  "whitelist_file": "whitelist.json",
  "use_whitelist": false
}
EOF

sudo chown factorio:factorio /home/factorio/factorio-data/server-settings.json

Configuration explanation:

  • name: Server name displayed in server list
  • max_players: Maximum concurrent players (default 255)
  • visibility.public: Enable to show in server browser
  • pause_when_empty: Pause game when no players are online
  • autosave_interval: Minutes between autosaves
  • autosave_slots: Number of autosave copia de seguridads to keep
  • allow_commands: "admins-only" restricts commands to admins
  • afk_autokick_interval: Minutes before kicking AFK players (0 = disabled)
  • only_admins_can_trigger_incidents: Controls incident spawning permissions

Map Generation and Presets

Create map generation presets:

sudo tee /home/factorio/factorio-data/map-gen-settings.json > /dev/null <<'EOF'
{
  "terrain_segmentation": "normal",
  "water": "normal",
  "starting_area": "normal",
  "peaceful_mode": false,
  "cliff_settings": {
    "cliff_elevation_0": 10,
    "cliff_elevation_interval": 10,
    "cliff_richness": 0.8
  },
  "autoplace_controls": {
    "coal": {
      "frequency": "normal",
      "size": "normal",
      "richness": "normal"
    },
    "stone": {
      "frequency": "normal",
      "size": "normal",
      "richness": "normal"
    },
    "iron-ore": {
      "frequency": "normal",
      "size": "normal",
      "richness": "normal"
    },
    "copper-ore": {
      "frequency": "normal",
      "size": "normal",
      "richness": "normal"
    },
    "crude-oil": {
      "frequency": "normal",
      "size": "normal",
      "richness": "normal"
    },
    "trees": {
      "frequency": "normal",
      "size": "normal",
      "richness": "normal"
    },
    "enemy-base": {
      "frequency": "normal",
      "size": "normal",
      "richness": "normal"
    }
  },
  "seed": 0
}
EOF

sudo chown factorio:factorio /home/factorio/factorio-data/map-gen-settings.json

Create world with custom map generation:

# Stop server first
sudo systemctl stop factorio.service

# Create new world with specific seed and settings
sudo -u factorio /home/factorio/factorio-server/factorio/bin/x64/factorio \
    --create /home/factorio/factorio-data/saves/new_world.zip \
    --map-gen-settings /home/factorio/factorio-data/map-gen-settings.json

# Restart server with new world
sudo systemctl start factorio.service

RCON Configuration

Enable RCON for remote console access. Add to server startup script:

# RCON port configuration (add to start script)
RCON_PORT=27015
RCON_PASSWORD="SecureRconPassword"

Create RCON client script for remote administration:

sudo tee /home/factorio/factorio-server/rcon_client.py > /dev/null <<'EOF'
#!/usr/bin/env python3

import socket
import json
import sys
import time

class FactorioRCON:
    def __init__(self, host, port, password):
        self.host = host
        self.port = port
        self.password = password
        self.socket = None
        self.command_id = 0
    
    def connect(self):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.connect((self.host, self.port))
        
        # Authenticate
        auth_msg = {
            "jsonrpc": "2.0",
            "method": "Auth",
            "params": {"password": self.password},
            "id": 1
        }
        self.send_command(auth_msg)
        response = self.socket.recv(1024).decode()
        print(f"Auth response: {response}")
    
    def send_command(self, command_dict):
        msg = json.dumps(command_dict) + "\n"
        self.socket.send(msg.encode())
    
    def execute_command(self, command):
        self.command_id += 1
        cmd_msg = {
            "jsonrpc": "2.0",
            "method": "call",
            "params": {"method": command},
            "id": self.command_id
        }
        self.send_command(cmd_msg)
        
        response = self.socket.recv(4096).decode()
        return response
    
    def close(self):
        if self.socket:
            self.socket.close()

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: rcon_client.py <command>")
        sys.exit(1)
    
    rcon = FactorioRCON("127.0.0.1", 27015, "SecureRconPassword")
    try:
        rcon.connect()
        result = rcon.execute_command(sys.argv[1])
        print(result)
    finally:
        rcon.close()
EOF

sudo chmod +x /home/factorio/factorio-server/rcon_client.py
sudo chown factorio:factorio /home/factorio/factorio-server/rcon_client.py

Common RCON commands:

# Player management
/promote playername          # Make player admin
/demote playername          # Remove admin status
/kick playername            # Kick a player
/ban playername             # Ban a player
/unban playername           # Unban a player
/ban-by-account playername  # Ban by account

# Server control
/help                       # Show available commands
/save                       # Force save world
/quit                       # Graceful shutdown
/evolution                  # Show evolution factor

# Game control
/cheat                      # Enable cheat mode
/toggle-pause              # Pause/unpause game
/time                      # Show elapsed time
/seed                      # Show map seed

# Messaging
/say message               # Broadcast to all players
/whisper player message    # Send private message

Mod Instalaation

Descarga mods from the Factorio mod portal:

cd /home/factorio/factorio-data/mods

# Mods can be downloaded from https://mods.factorio.com/
# Popular mods:
# - Bob's Mods (comprehensive content expansion)
# - Angel's Mods (production extensions)
# - Industrial Revolution 2
# - Space Exploration

# Download and extract mod (example)
sudo -u factorio wget https://github.com/factoriotools/factorio-mirror/releases/download/latest/some-mod.zip
sudo -u factorio unzip -o some-mod.zip

# List installed mods
ls -la /home/factorio/factorio-data/mods/

Create mod configuration file:

sudo tee /home/factorio/factorio-data/saves/mods.json > /dev/null <<'EOF'
{
  "mods": [
    {
      "name": "base",
      "enabled": true
    },
    {
      "name": "example-mod",
      "enabled": true
    }
  ]
}
EOF

sudo chown factorio:factorio /home/factorio/factorio-data/saves/mods.json

Firewall and Ports

Configura firewall for Factorio:

# Default game port (TCP/UDP)
GAME_PORT=34197

# Optional RCON port
RCON_PORT=27015

# Configure UFW
sudo ufw allow 34197/tcp
sudo ufw allow 34197/udp
sudo ufw allow 27015/tcp

# For iptables
sudo iptables -A INPUT -p tcp --dport 34197 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 34197 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 27015 -j ACCEPT

# Verify
sudo ufw status numbered

Ejecución con Systemd

Create servicio systemd:

sudo tee /etc/systemd/system/factorio.service > /dev/null <<'EOF'
[Unit]
Description=Factorio Headless Server
After=network.target
Wants=network-online.target

[Service]
Type=simple
User=factorio
Group=factorio
WorkingDirectory=/home/factorio/factorio-data
EnvironmentFile=/home/factorio/factorio-server/server.env

ExecStart=/home/factorio/factorio-server/start_server.sh

Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal

# Resource limits
LimitNOFILE=65536
LimitNPROC=4096

# Security
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/home/factorio/factorio-data

[Install]
WantedBy=multi-user.target
EOF

Create environment file:

sudo tee /home/factorio/factorio-server/server.env > /dev/null <<'EOF'
SAVE_NAME=factorio_saves
ADMIN_PASSWORD=changeme
GAME_PASSWORD=
EOF

sudo chown factorio:factorio /home/factorio/factorio-server/server.env
sudo chmod 600 /home/factorio/factorio-server/server.env

Enable and start:

sudo systemctl daemon-reload
sudo systemctl enable factorio.service
sudo systemctl start factorio.service
sudo systemctl status factorio.service

Monitor logs:

sudo journalctl -u factorio.service -f
tail -f /home/factorio/factorio-data/logs/factorio_$(date +%Y%m%d).log

Copia de seguridad y recuperación

Crea unutomated copia de seguridad script:

sudo tee /home/factorio/backup_factorio.sh > /dev/null <<'EOF'
#!/bin/bash

DATA_DIR="/home/factorio/factorio-data"
BACKUP_DIR="$DATA_DIR/backups"
RETENTION_DAYS=30
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

mkdir -p "$BACKUP_DIR"

# Backup saves and configurations
tar -czf "$BACKUP_DIR/factorio_backup_${TIMESTAMP}.tar.gz" \
    -C "$DATA_DIR" saves/ mods/ \
    2>/dev/null

if [ $? -eq 0 ]; then
    SIZE=$(du -sh "$BACKUP_DIR/factorio_backup_${TIMESTAMP}.tar.gz" | awk '{print $1}')
    echo "[$(date)] Backup created: ${SIZE}"
else
    echo "[$(date)] Backup failed!" >&2
    exit 1
fi

# Cleanup old backups
find "$BACKUP_DIR" -name "factorio_backup_*.tar.gz" -mtime +${RETENTION_DAYS} -delete
EOF

sudo chmod +x /home/factorio/backup_factorio.sh
sudo chown factorio:factorio /home/factorio/backup_factorio.sh

Add to crontab:

sudo tee -a /var/spool/cron/crontabs/factorio > /dev/null <<'EOF'
0 3 * * * /home/factorio/backup_factorio.sh >> /home/factorio/factorio-data/logs/backup.log 2>&1
EOF

Restore copia de seguridad:

sudo systemctl stop factorio.service
BACKUP="/home/factorio/factorio-data/backups/factorio_backup_20240101_030000.tar.gz"
sudo -u factorio tar -xzf "$BACKUP" -C /home/factorio/factorio-data/
sudo systemctl start factorio.service

Administration

Crea undmin management script:

sudo tee /home/factorio/manage_admins.sh > /dev/null <<'EOF'
#!/bin/bash

# Add admin to whitelist
add_admin() {
    python3 /home/factorio/factorio-server/rcon_client.py "/promote $1"
}

# Remove admin
remove_admin() {
    python3 /home/factorio/factorio-server/rcon_client.py "/demote $1"
}

case "$1" in
    add)
        add_admin "$2"
        ;;
    remove)
        remove_admin "$2"
        ;;
    *)
        echo "Usage: $0 {add|remove} playername"
        ;;
esac
EOF

sudo chmod +x /home/factorio/manage_admins.sh

Supervisión

Create monitoreo script:

sudo tee /home/factorio/monitor_factorio.sh > /dev/null <<'EOF'
#!/bin/bash

echo "=== Factorio Server Status ==="
echo "Timestamp: $(date)"
echo ""

# Service status
if systemctl is-active --quiet factorio.service; then
    echo "✓ Service is running"
else
    echo "✗ Service is NOT running"
    exit 1
fi

# Process info
PID=$(pgrep -f "factorio.*start-server")
if [ ! -z "$PID" ]; then
    MEM=$(ps -p $PID -o rss= | awk '{print $1/1024 " MB"}')
    CPU=$(ps -p $PID -o %cpu= | awk '{print $1 "%"}')
    echo "Memory: $MEM"
    echo "CPU: $CPU"
fi

# Port status
echo ""
if ss -tlnp | grep -q ":34197"; then
    echo "✓ Game port 34197 listening"
else
    echo "✗ Game port not listening"
fi

# Disk usage
echo ""
USAGE=$(df -h /home/factorio/factorio-data | awk 'NR==2 {print $5}')
echo "Disk usage: $USAGE"

# Latest save file
echo ""
LATEST=$(ls -t /home/factorio/factorio-data/saves/*.zip 2>/dev/null | head -1)
if [ ! -z "$LATEST" ]; then
    MODIFIED=$(date -r "$LATEST" '+%Y-%m-%d %H:%M:%S')
    echo "Latest save: $(basename $LATEST) - $MODIFIED"
fi
EOF

sudo chmod +x /home/factorio/monitor_factorio.sh

Conclusión

Your Factorio headless server is now fully operational with RCON support, mod capability, and automated copia de seguridads. Factorio provides engaging cooperative factory-building experiences with incredible longevity and depth.

Key takeaways:

  • Factorio is lightweight and can run on modest hardware
  • Configura server settings appropriately for your playstyle
  • Use mods to enhance gameplay experiences
  • Implement regular automated copia de seguridads
  • Monitor server rendimiento, which is generally stable
  • Use admin commands for community management
  • Plan regular maintenance during off-peak hours

A well-maintained Factorio server can support hundreds of hours of collaborative factory building for your community.