VPS & Dedicated Server Management

From initial provisioning to production hardening — configure and manage virtual private servers and dedicated servers on both Linux and Windows platforms.

VPS vs. Dedicated Server: When to Use Each

Understanding the difference is critical for choosing the right hosting for your project:

Feature VPS (Virtual Private Server) Dedicated Server
HardwareShared physical host, isolated via hypervisorEntire physical machine is yours
ResourcesAllocated vCPUs, RAM, storageFull CPU, RAM, all disks
ScalabilityResize on the fly (most providers)Hardware upgrade = migration or swap
Cost$5–$100/mo typical$80–$500+/mo typical
Best ForWeb apps, dev environments, small-to-mid traffic sitesHigh-traffic sites, databases, compliance, game servers
Root AccessFull root/admin accessFull root/admin access
Choosing a Provider

Popular VPS providers include DigitalOcean, Linode (Akamai), Vultr, and AWS Lightsail. For dedicated servers, OVH, Hetzner, and Liquid Web are well-regarded. Many hosting companies like InMotion and A2 Hosting offer both with managed support options.

Linux VPS: Initial Setup

After provisioning a new Linux VPS (Ubuntu/Debian or CentOS/AlmaLinux), these are the first steps to secure and configure it:

Step 1: Connect & Update

# Connect via SSH (see our SSH Essentials guide)
ssh root@your_server_ip

# Update all packages immediately
# Ubuntu/Debian
apt update && apt upgrade -y

# CentOS/AlmaLinux/Rocky
dnf update -y

Step 2: Create a Non-Root User

# Never run services as root in production
adduser deploy
usermod -aG sudo deploy    # Ubuntu/Debian
# usermod -aG wheel deploy # CentOS/AlmaLinux

# Copy SSH keys to new user
rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy

# Test login in a NEW terminal before closing root session
ssh deploy@your_server_ip

Step 3: Secure SSH

# Edit /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
Port 2222                    # Change from default 22
AllowUsers deploy

# Restart SSH
systemctl restart sshd

See our SSH Essentials guide for full key auth setup and hardening.

Step 4: Configure the Firewall

# UFW (Ubuntu/Debian)
ufw default deny incoming
ufw default allow outgoing
ufw allow 2222/tcp           # SSH (your custom port)
ufw allow 80/tcp             # HTTP
ufw allow 443/tcp            # HTTPS
ufw enable

# firewalld (CentOS/AlmaLinux/Rocky)
firewall-cmd --permanent --add-port=2222/tcp
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

Step 5: Install fail2ban

# Ubuntu/Debian
apt install fail2ban -y

# CentOS/AlmaLinux
dnf install epel-release -y && dnf install fail2ban -y

# Enable and start
systemctl enable fail2ban
systemctl start fail2ban

# Check status
fail2ban-client status sshd

Linux: Web Server Configuration

Nginx Setup

# Install Nginx
apt install nginx -y          # Ubuntu/Debian
dnf install nginx -y          # CentOS/AlmaLinux

# Start and enable
systemctl enable nginx
systemctl start nginx

# Test configuration
nginx -t

# Basic server block (/etc/nginx/sites-available/mysite)
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/mysite;
    index index.html index.php;

    location / {
        try_files $uri $uri/ =404;
    }

    # PHP-FPM
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Deny hidden files
    location ~ /\. {
        deny all;
    }
}

# Enable the site
ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

Apache Setup

# Install Apache + PHP
apt install apache2 libapache2-mod-php php php-mysql -y

# Enable modules
a2enmod rewrite ssl headers

# Virtual host (/etc/apache2/sites-available/mysite.conf)
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/mysite

    <Directory /var/www/mysite>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/mysite_error.log
    CustomLog ${APACHE_LOG_DIR}/mysite_access.log combined
</VirtualHost>

# Enable site and restart
a2ensite mysite.conf
systemctl reload apache2

PHP-FPM Configuration

# Install PHP-FPM with common extensions
apt install php8.2-fpm php8.2-mysql php8.2-curl php8.2-gd \
  php8.2-mbstring php8.2-xml php8.2-zip php8.2-intl -y

# Key settings (/etc/php/8.2/fpm/php.ini)
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
max_input_vars = 5000

# Pool config (/etc/php/8.2/fpm/pool.d/www.conf)
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10

systemctl restart php8.2-fpm

Linux: Control Panels

Plesk on Linux

Plesk is a commercial server management panel that supports both Linux and Windows. It provides a web-based GUI for managing websites, databases, email, DNS, and SSL certificates.

# One-click Plesk installation (official installer)
sh <(curl https://autoinstall.plesk.com/one-click-installer \
  || wget -O - https://autoinstall.plesk.com/one-click-installer)

# After installation, access at:
# https://your_server_ip:8443

# CLI management via plesk bin
plesk bin domain --create example.com -hosting true \
  -ip your_server_ip -login admin -passwd "secure_pass"

# List all domains
plesk bin domain --list

# Manage PHP version per domain
plesk bin domain -u example.com -php_handler_id plesk-php82-fpm

# Restart Plesk services
plesk repair web -y
Plesk vs cPanel

Plesk works on both Linux and Windows, has a cleaner UI, and includes WordPress Toolkit. It's ideal when you manage both Linux and Windows servers.
cPanel/WHM is Linux-only, the industry standard for shared hosting resellers. WHM is the server-level admin panel, cPanel is the per-account panel.
Both handle domains, email, databases, SSL, DNS, and backups through a GUI.

cPanel/WHM on Linux

# Install WHM/cPanel (CentOS/AlmaLinux only)
cd /home && curl -o latest -L https://secup.cpanel.net/latest
sh latest

# Access WHM at: https://your_server_ip:2087 (root login)
# Access cPanel at: https://your_server_ip:2083 (account login)

# CLI: create an account
/scripts/createacct --domain example.com --user exampleusr

# CLI: list accounts
whmapi1 listaccts

# Restart services
/scripts/restartsrv_httpd
/scripts/restartsrv_mysql

Windows Server: Setup & Configuration

Windows Server is used when your stack requires IIS, ASP.NET, MSSQL, or Active Directory. Common editions include Windows Server 2019 and 2022.

Initial Configuration

# PowerShell: Set hostname
Rename-Computer -NewName "WEBSERVER01" -Restart

# Configure static IP
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 10.0.0.5 `
  -PrefixLength 24 -DefaultGateway 10.0.0.1
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" `
  -ServerAddresses 8.8.8.8,8.8.4.4

# Enable Windows Firewall rules
New-NetFirewallRule -DisplayName "HTTP" -Direction Inbound `
  -Protocol TCP -LocalPort 80 -Action Allow
New-NetFirewallRule -DisplayName "HTTPS" -Direction Inbound `
  -Protocol TCP -LocalPort 443 -Action Allow
New-NetFirewallRule -DisplayName "RDP" -Direction Inbound `
  -Protocol TCP -LocalPort 3389 -Action Allow

# Enable Windows Updates
Install-Module PSWindowsUpdate -Force
Get-WindowsUpdate -Install -AcceptAll -AutoReboot

IIS Web Server

# Install IIS with common features
Install-WindowsFeature Web-Server, Web-Asp-Net45, `
  Web-Mgmt-Console, Web-Scripting-Tools, `
  Web-Http-Redirect, Web-Url-Auth, Web-IP-Security

# Install ASP.NET Core hosting bundle (download from Microsoft)
# Then configure a site in IIS Manager or via PowerShell:

Import-Module WebAdministration

# Create a new site
New-Website -Name "MySite" -PhysicalPath "C:\inetpub\mysite" `
  -Port 80 -HostHeader "example.com"

# Create an application pool
New-WebAppPool -Name "MySitePool"
Set-ItemProperty "IIS:\AppPools\MySitePool" `
  -Name processModel.identityType -Value "ApplicationPoolIdentity"
Set-ItemProperty "IIS:\Sites\MySite" `
  -Name applicationPool -Value "MySitePool"

# Enable HTTPS binding (after installing certificate)
New-WebBinding -Name "MySite" -Protocol "https" `
  -Port 443 -HostHeader "example.com" -SslFlags 1

Plesk on Windows Server

# Download Plesk installer from plesk.com
# Run the installer — it will configure IIS, mail, DNS, etc.

# After installation, access at:
# https://your_server_ip:8443

# Plesk on Windows manages:
# - IIS websites and application pools
# - ASP.NET and PHP configurations
# - SQL Server and MySQL databases
# - SSL certificates
# - DNS zones and mail
# - Windows Firewall rules

# CLI examples (run in Plesk command prompt)
plesk bin domain --create example.com -hosting true
plesk bin database --create mydb -domain example.com -type mssql
plesk bin domain -u example.com -asp_dot_net true

Windows Server Security

# Change default RDP port (registry + firewall)
Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" `
  -Name PortNumber -Value 33389

New-NetFirewallRule -DisplayName "RDP Custom" -Direction Inbound `
  -Protocol TCP -LocalPort 33389 -Action Allow

# Disable SMBv1 (security risk)
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart

# Enable Windows Defender
Set-MpPreference -DisableRealtimeMonitoring $false

# Configure account lockout policy
net accounts /lockoutthreshold:5 /lockoutduration:30 /lockoutwindow:30

# Enable audit logging
auditpol /set /category:"Logon/Logoff" /success:enable /failure:enable
auditpol /set /category:"Account Logon" /success:enable /failure:enable

Performance Tuning

Linux VPS Optimization

# Check current resource usage
free -h                       # Memory
df -h                         # Disk
nproc                        # CPU cores
uptime                       # Load average

# Swap file (if VPS has limited RAM)
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab

# Kernel tuning (/etc/sysctl.conf)
# Increase max connections
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535

# TCP optimization
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15

# Apply changes
sysctl -p

Windows Server Optimization

# Check resource usage
Get-Process | Sort-Object CPU -Descending | Select -First 10
Get-Counter '\Processor(_Total)\% Processor Time'
Get-Counter '\Memory\Available MBytes'

# IIS Application Pool recycling (prevent memory leaks)
Set-ItemProperty "IIS:\AppPools\MySitePool" `
  -Name recycling.periodicRestart.time -Value "1.00:00:00"
Set-ItemProperty "IIS:\AppPools\MySitePool" `
  -Name recycling.periodicRestart.privateMemory -Value 1048576

# Disable unnecessary services
Set-Service -Name "Spooler" -StartupType Disabled  # Print spooler
Set-Service -Name "XblGameSave" -StartupType Disabled

SSL Certificates on VPS/Dedicated

# Let's Encrypt with Certbot (Linux)
apt install certbot python3-certbot-nginx -y    # For Nginx
apt install certbot python3-certbot-apache -y   # For Apache

# Obtain and auto-configure SSL
certbot --nginx -d example.com -d www.example.com

# Auto-renewal (certbot adds a timer automatically)
certbot renew --dry-run

# Windows: Use win-acme for Let's Encrypt
# Download from https://www.win-acme.com/
# Run wacs.exe and follow the prompts for IIS binding

For more details, see our SSL Certificate Installation guide.

Backup Strategies

# Linux: Full server backup with rsync
rsync -avz --delete /var/www/ backup@backup-server:/backups/www/
rsync -avz /etc/nginx/ backup@backup-server:/backups/nginx-config/

# Automated daily backup script
#!/bin/bash
DATE=$(date +%Y-%m-%d)
BACKUP_DIR="/backups/$DATE"
mkdir -p $BACKUP_DIR
tar -czf $BACKUP_DIR/www.tar.gz /var/www/
mysqldump --all-databases | gzip > $BACKUP_DIR/all-databases.sql.gz

# Windows: Windows Server Backup
Install-WindowsFeature Windows-Server-Backup
wbadmin start backup -backuptarget:E: -include:C: -allCritical -quiet

# Plesk backup (works on both Linux and Windows)
plesk bin pleskbackup domains-only --output-file=/backups/domains.tar
The 3-2-1 Backup Rule

Keep 3 copies of your data, on 2 different types of media, with 1 copy offsite. For servers, this means: local backup + remote server/NAS + cloud storage (S3, Backblaze B2, etc.).

Monitoring & Maintenance

# Linux: Install monitoring tools
apt install htop iotop nethogs -y

# Check for listening ports
ss -tulnp

# Linux: Unattended security updates
apt install unattended-upgrades -y
dpkg-reconfigure -plow unattended-upgrades

# Windows: Check event logs via PowerShell
Get-EventLog -LogName System -Newest 50 | Where-Object {$_.EntryType -eq "Error"}
Get-EventLog -LogName Application -Newest 50 | Where-Object {$_.EntryType -eq "Error"}
Pro Tip

Set up uptime monitoring with a free service like UptimeRobot or Hetrixtools. These will alert you via email, SMS, or Slack when your server goes down — often before your users even notice. For resource monitoring, Netdata (Linux) provides real-time dashboards with zero configuration.