How to Set Up a KVM VPS from Scratch: Complete Linux Server Configuration Guide
A freshly provisioned KVM VPS arrives as a blank Linux environment — root SSH access, a minimal operating system install, and nothing else. Configuring it correctly from the start determines whether your server is secure, performant, and easy to maintain. This guide walks through the complete process of setting up a KVM VPS from scratch, from first login to production-ready deployment.
Prerequisites
Before starting, you need:
- A provisioned KVM VPS with a public IP address (and your root SSH credentials or initial password)
- An SSH client — Terminal on macOS/Linux, or Windows Terminal / PuTTY on Windows
- Basic familiarity with Linux command-line navigation
This guide assumes Ubuntu 22.04 LTS as the operating system, which is the most widely supported distribution for production VPS deployments. The steps apply to Debian 12 with minor package name differences.
Step 1: First Login and System Update
Connect to your VPS using SSH:
ssh root@YOUR_SERVER_IP
Accept the host key fingerprint on first connection. Once logged in, update all packages immediately:
apt update && apt upgrade -y
This ensures you start with the latest security patches applied. On a fresh Ubuntu install, this process takes 1–3 minutes.
Step 2: Create a Non-Root User
Running everything as root is a security risk. Create a dedicated user account for your daily operations:
adduser yourname
usermod -aG sudo yourname
Replace yourname with your preferred username. The sudo group membership allows this user to run administrative commands when needed without logging in as root.
Step 3: Configure SSH Key Authentication
Password-based SSH authentication is vulnerable to brute-force attacks. SSH key pairs eliminate this risk entirely.
On your local machine (not the server), generate a key pair if you do not already have one:
ssh-keygen -t ed25519 -C "your-email@example.com"
Copy your public key to the server:
ssh-copy-id yourname@YOUR_SERVER_IP
Test that key-based login works by opening a new terminal and connecting:
ssh yourname@YOUR_SERVER_IP
Once you confirm key-based login works, disable password authentication by editing the SSH configuration:
sudo nano /etc/ssh/sshd_config
Locate and set these values:
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
Restart SSH to apply the changes:
sudo systemctl restart sshd
Step 4: Configure the Firewall
Ubuntu ships with UFW (Uncomplicated Firewall). Enable it and configure rules before proceeding:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Verify the rules are active:
sudo ufw status verbose
This configuration allows SSH (port 22), HTTP (port 80), and HTTPS (port 443) while blocking all other inbound connections. Add additional rules as needed for your specific applications (e.g., sudo ufw allow 3306/tcp for MySQL if you need external database access, though this is generally not recommended).
Step 5: Install Fail2ban for Brute-Force Protection
Even with SSH key authentication enabled, installing Fail2ban adds an extra layer of protection by monitoring log files and banning IP addresses that show malicious patterns:
sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
The default configuration protects SSH. To check the current ban list:
sudo fail2ban-client status sshd
Step 6: Set the Hostname and Timezone
Set a meaningful hostname for your server:
sudo hostnamectl set-hostname your-server-name
Set the correct timezone (important for log timestamps and scheduled jobs):
sudo timedatectl set-timezone America/New_York
Replace America/New_York with your actual timezone. List available timezones with timedatectl list-timezones.
Step 7: Install and Configure a Web Server (Nginx)
Nginx is the recommended web server for most VPS deployments due to its performance, low memory footprint, and flexibility as a reverse proxy.
sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx
Visit your server’s IP address in a browser — you should see the default Nginx welcome page, confirming the web server is running. To serve your own content, create a server block configuration:
sudo nano /etc/nginx/sites-available/yourdomain.com
A basic server block configuration:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
root /var/www/yourdomain.com;
index index.html index.php;
location / {
try_files $uri $uri/ =404;
}
}
Enable the site and reload Nginx:
sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Step 8: Install PHP-FPM (for PHP Applications)
For WordPress and other PHP applications, install PHP-FPM:
sudo apt install php8.2-fpm php8.2-mysql php8.2-curl php8.2-gd php8.2-mbstring php8.2-xml php8.2-zip -y
Update your Nginx server block to process PHP files by adding inside the server {} block:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
}
Step 9: Install and Secure MariaDB
For database-driven applications, MariaDB is the recommended MySQL-compatible database:
sudo apt install mariadb-server -y
sudo mysql_secure_installation
The mysql_secure_installation script walks you through setting a root password, removing test databases, and disabling remote root login — complete all steps. Then create a dedicated database and user for your application:
sudo mysql -u root -p
CREATE DATABASE myapp_db;
CREATE USER 'myapp_user'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON myapp_db.* TO 'myapp_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Step 10: Set Up SSL with Let’s Encrypt
HTTPS is mandatory for any production site. Certbot automates SSL certificate issuance from Let’s Encrypt:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Follow the prompts to issue and install the certificate. Certbot automatically configures Nginx to redirect HTTP to HTTPS and sets up automatic certificate renewal.
Step 11: Configure Automatic Security Updates
Keep your server patched automatically without manual intervention:
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgrades
Select “Yes” when prompted to enable automatic updates. This applies security patches automatically while leaving application packages under manual control.
Step 12: Set Up Server Monitoring
Install a lightweight monitoring agent so you can observe CPU, memory, and disk usage over time. Netdata is an excellent open-source option:
wget -O /tmp/netdata-install.sh https://my-netdata.io/kickstart.sh
bash /tmp/netdata-install.sh
Alternatively, set up basic monitoring with a service like UptimeRobot (free tier available) to receive email or SMS alerts when your server becomes unreachable.
Post-Setup Checklist
Before declaring your VPS production-ready, verify:
- Root login is disabled and SSH key authentication is the only login method
- UFW firewall is active with only necessary ports open
- Fail2ban is running and protecting SSH
- SSL certificate is installed and HTTPS redirects are working
- Automatic security updates are enabled
- Backups are configured (provider snapshots + your own offsite backup)
- Monitoring alerts are set up
Next Steps
With the base configuration complete, you can deploy your application — whether WordPress, a Node.js app, a Python API, or a custom stack. If you are starting with a KVM VPS and need a provider with NVMe storage, reliable uptime, and full root access, explore KVM VPS plans at VPS.DO. The clean provisioning process and responsive support make initial setup straightforward even for teams new to self-managed server infrastructure.