Skip to main content

How to Set Up a VPS in 2026: A Practical No-Fluff Guide

Terminal window showing VPS setup commands on a Linux server with SSH connection and firewall configuration
Terminal window showing VPS setup commands on a Linux server with SSH connection and firewall configuration
By: Abdulkader Safi
Software Engineer at DSRPT
10 min read

TL;DR

A VPS is just a Linux box you rent. The first hour matters more than the next year. Update the system, ditch the root login, set up SSH keys, lock the firewall, and only then install your stack. Most "hacked VPS" stories start with skipping one of those five steps.

The first VPS I ever spun up got compromised in 11 hours. I logged back in the next morning to find a crypto miner pinning the CPU at 100% and a stranger's SSH key sitting in authorized_keys. I had skipped exactly one step: I left password authentication on while I "just tested if Apache works." That is all it took.

Here is the thing about VPS setup. The internet treats every new IP address like a target the moment it goes live. Within minutes, automated scanners are knocking on port 22 trying default passwords. So the order matters. You secure the box first. Install the app second. Not the other way around.

This guide walks you through the exact sequence I run on every new VPS now. Whether you are deploying a Laravel app, hosting a WordPress site, or running an n8n instance, the first 45 minutes look the same.

What is a VPS and why use one

A VPS (Virtual Private Server) is one slice of a physical server, ring-fenced with its own CPU allocation, RAM, disk, and root access. You get a full Linux box at a fraction of the cost of dedicated hardware. Plans start around $5 to $10 a month and scale up.

You use a VPS when shared hosting starts hurting. Common triggers:

  • Your app needs a process that runs in the background (queue workers, cron, websockets)
  • You need to install custom software the host will not approve
  • You need root access to tune PHP, Node, or database settings
  • You want one box hosting multiple sites without paying per-site

If you are still weighing the call, we covered the trade-offs in Choosing Between VPS, Cloud, and Managed Hosting for Your Business. The short version: VPS wins on price and control. Cloud wins on scale and resilience. Managed wins when you do not want to think about any of this.

Before you start: what you need

Three things:

  1. A VPS plan from any provider (Hostinger, DigitalOcean, Linode, Hetzner, Vultr all work fine)
  2. SSH credentials from your provider dashboard: the server IP, the SSH port (usually 22), and the root password
  3. A terminal. macOS and Linux already have one. On Windows, install PuTTY or use the built-in OpenSSH client in PowerShell

Pick an OS when prompted. Ubuntu 24.04 LTS or Debian 12 are the safest defaults for general use. CentOS Stream and AlmaLinux work fine if you prefer the RHEL family. The commands in this guide use Ubuntu/Debian syntax, but I will note the CentOS equivalents where they matter.

Step 1: Log in for the first time

Open your terminal and connect:

ssh root@YOUR_SERVER_IP

If the provider gave you a non-default SSH port:

ssh -p 2222 root@YOUR_SERVER_IP

You will get a host key fingerprint warning the first time. Type yes, paste the root password, and you are in.

You are now staring at a clean Linux box. Resist the urge to install anything yet.

Step 2: Update everything

Patches are not optional. The kernel and packages on your fresh VPS image are almost certainly weeks or months behind. Update before you do anything else.

Ubuntu / Debian:

apt update && apt upgrade -y

CentOS / AlmaLinux:

dnf update -y

If the kernel updated, reboot:

reboot

Wait 30 seconds, then SSH back in.

Step 3: Create a non-root user

Never use root for daily work. One typo with root active and you can wipe a directory you needed. Create a sudo user instead.

adduser yourname
usermod -aG sudo yourname

(On CentOS, the group is wheel instead of sudo.)

You will be asked for a password and some optional details (name, phone). Skip the optional bits by pressing Enter.

Test the new user from a second terminal window before you do anything else:

ssh yourname@YOUR_SERVER_IP
sudo whoami

If sudo whoami returns root, you are good. Keep that second window open. If you lock yourself out in the next steps, this window is your escape hatch.

Step 4: Set up SSH keys

Passwords are guessable. SSH keys are not (in any practical sense). Generate a key pair on your local machine:

ssh-keygen -t ed25519 -C "your_email@example.com"

Accept the default location. Set a passphrase if you want extra security at the cost of typing it occasionally.

Copy the public key to your VPS:

ssh-copy-id yourname@YOUR_SERVER_IP

If ssh-copy-id is not available (Windows without WSL, for example), do it manually:

ssh yourname@YOUR_SERVER_IP
mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys

Paste the contents of your local ~/.ssh/id_ed25519.pub into the file. Save, then:

chmod 600 ~/.ssh/authorized_keys

Now log out and try logging back in. If it works without asking for a password, your key is set up correctly.

Step 5: Lock down SSH

This is where most people stop. Do not stop here. The default SSH config is way too permissive for a public-facing server.

Edit the SSH daemon config:

sudo nano /etc/ssh/sshd_config

Find and change these lines (uncomment them if they have a # in front):

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

Optional but recommended: change the SSH port from 22 to something obscure like 2222 or 49152. It does not stop a determined attacker but it kills 99% of automated scanner traffic, which means cleaner logs:

Port 2222

Save the file (Ctrl+O, Enter, Ctrl+X) and restart SSH:

sudo systemctl restart sshd

Do not close your existing session yet. Open a third terminal and try logging in with the new settings:

ssh -p 2222 yourname@YOUR_SERVER_IP

If it works, you can close the old root session. If it does not, fix the config from the existing session before logging out.

Step 6: Set up a firewall

UFW (Uncomplicated Firewall) is the easiest option on Ubuntu/Debian. It is a friendly wrapper around iptables.

sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 2222/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw enable

Check it is active:

sudo ufw status verbose

If you changed the SSH port in Step 5, make sure you allow the new port before enabling the firewall. Locking yourself out of your own server is the most popular VPS mistake on the internet, and I have done it three times.

For CentOS/AlmaLinux, use firewalld instead:

sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Step 7: Install Fail2Ban

Fail2Ban watches your logs and bans IPs that fail repeated login attempts. It catches the brute-force scanners that survive Step 5.

sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban

Create a local config so updates do not overwrite your settings:

sudo nano /etc/fail2ban/jail.local

Paste:

[sshd]
enabled = true
port = 2222
maxretry = 3
bantime = 1h
findtime = 10m

Restart:

sudo systemctl restart fail2ban

Within an hour of going live, you can run sudo fail2ban-client status sshd and watch the list of banned IPs grow. It is weirdly satisfying.

Step 8: Set the hostname and timezone

Small but important. A clean hostname helps when you have multiple servers, and the correct timezone makes logs readable.

sudo hostnamectl set-hostname myapp-prod-01
sudo timedatectl set-timezone Australia/Sydney

Replace the timezone with yours. List them with timedatectl list-timezones.

Step 9: Install your application stack

Only now do you install the actual app. The exact stack depends on what you are running:

LAMP (PHP + MySQL):

sudo apt install apache2 mysql-server php php-mysql -y
sudo mysql_secure_installation

LEMP (PHP + Nginx + MariaDB):

sudo apt install nginx mariadb-server php-fpm php-mysql -y
sudo mysql_secure_installation

Node.js:

curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install nodejs -y

Docker (my preferred approach for new projects):

curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker yourname

Log out and back in for the docker group change to take effect.

Step 10: Point your domain and add SSL

Once your app is reachable on the server IP, point your domain at it. In your DNS provider's dashboard, add an A record:

  • Name: @ (or your subdomain)
  • Type: A
  • Value: Your VPS IP

DNS propagation usually takes 5 to 60 minutes, occasionally up to 24 hours.

For SSL, use Certbot. It is free, automated, and renews itself:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Certbot will detect your Nginx config, edit it to handle HTTPS, and set up a renewal cron. For Apache, swap nginx for apache.

Step 11: Set up automatic backups

A server without backups is a ticking bomb. Two layers:

  1. Provider snapshots. Most VPS hosts offer automated snapshots for a few dollars a month. Turn them on. Set them to daily or every 12 hours.
  2. Application-level backups. Database dumps and file backups uploaded to S3, Backblaze B2, or another remote target. Use a tool like restic or borg for incremental backups, or write a simple mysqldump + rclone cron job.

Provider snapshots save you when the disk dies. Application backups save you when you accidentally DROP TABLE on the live database. You need both.

Step 12: Monitoring

You will not notice your server is slow until a customer tells you. Set up basic monitoring on day one:

  • Uptime monitoring: UptimeRobot or BetterUptime, free tiers are plenty
  • Resource monitoring: Netdata or htop for ad-hoc checks
  • Log alerts: A simple cron that emails you on disk usage above 85%

For deeper observability on production apps, you eventually want something proper. We dug into the cost of skipping this in Quality Assurance: Why Testing in Production Costs You.

Common mistakes I still see

A few patterns that bite people repeatedly:

  1. Skipping the firewall because "the app works fine without it." It does, until it does not.
  2. Using apt install without update first. You install stale, sometimes broken, package versions.
  3. Leaving database ports exposed. MySQL on 3306 to the world is a free invite to attackers. Bind to 127.0.0.1.
  4. No swap on small VPS plans. A 1GB RAM VPS without swap will OOM-kill processes randomly. Add a 2GB swap file.
  5. Running everything as root in Docker. Same security problems, fancier wrapper.

When you should not run your own VPS

A VPS is not always the right call. If your team does not have anyone who wants to maintain it, you are buying yourself a future incident. Managed hosting or PaaS (Vercel, Railway, Fly.io, DigitalOcean App Platform) is often the right answer for solo founders and small teams. We made the case for that in Managed Cloud Hosting: Stop Running Your Own Servers.

Run a VPS when:

  • You actually want the control
  • Your stack is too custom or too cheap to justify managed pricing
  • You have time to patch and respond to alerts
  • You enjoy this kind of work (some of us do)

Do not run a VPS when none of the above apply. You will save money on hosting and lose three weekends to a server outage.

What to do now

Block out 90 minutes this week. Spin up the cheapest VPS your provider sells, work through these 12 steps from a fresh image, and break it on purpose. Lock yourself out. Recover. Run nmap against your own IP and see what is open. The only way to feel comfortable on a Linux box is to live in one for a few hours.

When you are confident, deploy a real project to it. Start small. A simple Laravel app, a WordPress site, an n8n automation server. The setup process is identical no matter what you put on top.

And if you would rather we run the server for you while you focus on the actual product, we do that. But honestly, every founder should set up at least one VPS by hand. It demystifies an enormous amount of infrastructure and makes every conversation with your DevOps people land harder.

Frequently Asked Questions

How long does it take to set up a VPS for the first time?

A clean VPS setup takes about 45 to 90 minutes if you have never done it before. That covers the initial SSH login, system update, creating a non-root user, locking down SSH, and configuring the firewall. Installing your application stack (web server, database, runtime) usually adds another 30 to 60 minutes depending on what you are deploying.

Do I need to know Linux to manage a VPS?

Yes, but less than people think. You need to be comfortable with SSH, basic shell commands (cd, ls, sudo, nano, systemctl), and reading log files. You do not need to be a sysadmin. If a control panel like CyberPanel or Hostinger's hPanel is available, you can manage most day-to-day tasks through a UI and only drop to the shell for occasional tasks.

Is a VPS more secure than shared hosting?

A VPS is more isolated than shared hosting, so a neighbour's compromised site cannot leak into yours. But isolation is not security. A VPS gives you root access, which means you also own all the responsibility for patches, firewalls, SSH config, and updates. Shared hosting is patched by the provider. Managed VPS plans bridge that gap.

What is the difference between a VPS and a cloud server?

A VPS is a virtual slice of one physical server with fixed resources. A cloud server is a virtual machine sitting on a pool of hardware, so it can scale, migrate, and survive a single host failure. For most small to mid-sized projects, the practical difference is pricing and elasticity. VPS plans tend to be cheaper and predictable. Cloud is better when traffic spikes hard or you need to scale horizontally.

Should I disable root SSH login on my VPS?

Yes. Disable root SSH login immediately after creating a non-root sudo user with key-based authentication. Root is the most attacked username on the internet. Leaving it accessible over SSH is the single biggest reason fresh VPS servers get brute-forced within hours of being provisioned. Set `PermitRootLogin no` and `PasswordAuthentication no` in `/etc/ssh/sshd_config` and restart sshd.