How to Set Up a VPS from Scratch (Complete Beginner Guide)

3 min read
Beginner VPS Server Linux Setup Beginner

Quick Answer: 1) SSH in as root. 2) Create a non-root user with sudo. 3) Set up SSH keys and disable password login. 4) Configure UFW firewall. 5) Update everything. 6) Install what you need. Takes about 15 minutes.

Need a VPS? Vultr (free credit), DigitalOcean ($200 free credit), or RackNerd (cheap annual deals).

Choose a Provider

Provider Starting Price Best For
DigitalOcean $4/month Beginners, clean UI
Vultr , or RackNerd $3.50/month Budget, many locations
Hetzner $3.29/month Europe, best value
Linode $5/month Reliability
AWS Lightsail $3.50/month AWS ecosystem

Recommended specs for starters:

  • 1 vCPU, 1 GB RAM, 25 GB SSD — enough for a web server, proxy, or VPN
  • Ubuntu 22.04 LTS or Debian 12 — most tutorials target these
  • Location closest to your users

Step 1: First Login

Your provider gives you an IP and root password. SSH in:

ssh root@YOUR_SERVER_IP

First time connecting, you will see:

The authenticity of host 'x.x.x.x' can't be established.
ED25519 key fingerprint is SHA256:xxxxx
Are you sure you want to continue connecting (yes/no)?

Type yes.

Step 2: Update Everything

apt update && apt upgrade -y

This updates all packages to the latest versions. Do this first, every time.

Step 3: Create a Non-Root User

Never use root for daily operations. Create a user with sudo access:

# Create user
adduser sam

# Add to sudo group
usermod -aG sudo sam

# Verify
groups sam
# Should show: sam sudo

Step 4: Set Up SSH Keys

On your local machine:

# Generate key (if you don't have one)
ssh-keygen -t ed25519

# Copy key to server
ssh-copy-id sam@YOUR_SERVER_IP

Test it:

ssh sam@YOUR_SERVER_IP
# Should log in without password

Now disable password authentication:

sudo nano /etc/ssh/sshd_config

Change:

PasswordAuthentication no
PermitRootLogin no
sudo systemctl restart sshd

See our SSH Keys Guide and SSH Hardening Guide for more.

Step 5: Configure Firewall

# Allow SSH (before enabling!)
sudo ufw allow 22/tcp

# Enable firewall
sudo ufw enable

# Allow other services as needed
sudo ufw allow 80/tcp      # HTTP
sudo ufw allow 443/tcp     # HTTPS

# Check status
sudo ufw status

See our UFW Cheat Sheet for more.

Step 6: Set Timezone and Hostname

# Set timezone
sudo timedatectl set-timezone America/Chicago
# Or: sudo dpkg-reconfigure tzdata

# Set hostname
sudo hostnamectl set-hostname myserver

# Verify
timedatectl
hostname

Step 7: Install Essential Software

# Essential tools
sudo apt install -y \
  curl wget git htop \
  unzip vim nano \
  ufw fail2ban \
  build-essential

# Install Fail2ban for brute-force protection
sudo systemctl enable --now fail2ban

Step 8: Enable Automatic Security Updates

sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure unattended-upgrades
# Select "Yes"

This automatically installs security patches.

What to Install Next

Depends on what you are building:

Web Server

sudo apt install nginx -y
sudo systemctl enable --now nginx
sudo ufw allow "Nginx Full"
# Get SSL: sudo apt install certbot python3-certbot-nginx -y

See our Nginx Cheat Sheet and Reverse Proxy Guide.

Docker

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker sam
# Log out and back in for group to take effect

See our Docker Cheat Sheet.

VPN (WireGuard)

sudo apt install wireguard -y
# Or use SamNet-WG for easy management:
curl -sSL https://raw.githubusercontent.com/SamNet-dev/wg-orchestrator/main/install.sh | sudo bash

See our WireGuard Setup Guide.

Proxy Server (3X-UI)

bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)

See our 3X-UI Setup Guide.

Database

# PostgreSQL
sudo apt install postgresql -y

# MySQL
sudo apt install mysql-server -y

# Redis
sudo apt install redis-server -y

Post-Setup Checklist

echo "=== VPS Setup Checklist ==="
echo "OS updated: $(apt list --upgradable 2>/dev/null | wc -l) packages pending"
echo "Non-root user: $(who | awk '{print $1}' | head -1)"
echo "SSH key auth: $(grep PasswordAuthentication /etc/ssh/sshd_config | head -1)"
echo "Root login: $(grep PermitRootLogin /etc/ssh/sshd_config | head -1)"
echo "Firewall: $(sudo ufw status | head -1)"
echo "Fail2ban: $(systemctl is-active fail2ban)"
echo "Auto-updates: $(systemctl is-active unattended-upgrades 2>/dev/null || echo 'check manually')"
echo "Timezone: $(timedatectl | grep 'Time zone')"
echo "Hostname: $(hostname)"

See Also