Your First VPS: From Purchase to Launch, Step by Step
2026-09-21 · 9 min read
First-time buyers get stuck for a week on “which provider, which specs.” Your first server has exactly one goal: get it running. Buy the smallest box, get the site loading on it, worry about the rest later. This walks through in order, and every step says what “done” looks like.
Three decisions to make before buying
- Region: put the server near your target users. If you want to skip the filing hassle, pick Hong Kong, Singapore, or the US; mainland China servers need an ICP filing, which both individuals and companies can get — it just takes the regulator's review time.
- Specs: start with 1 CPU and 2GB RAM — plenty for a small personal site. Start bandwidth at the minimum and add more later.
- OS: pick the LTS long-term-support release of Ubuntu. Don't pick Windows — Linux is the mainstream for hosting sites, with way more tutorials.
Three things to check while ordering
First is renewal pricing — many providers are cheap the first year and double on renewal; it's the long-term cost that counts. Second is how bandwidth is billed: fixed bandwidth or by traffic — traffic billing can cost more for image-heavy sites. Third is whether snapshots (backups) cost money and how. A glance at these three dodges most “second-year bill shock.”
First four things to do once you have the server
The provider gives you an IP, a username (usually root), and a password or key. SSH in, update the system first, then do these four:
- Change to a strong password, or switch to key login and disable password login entirely
- Open ports 22 (SSH), 80 (HTTP), 443 (HTTPS) in the provider's security group (firewall)
- Install Node.js (the version your project requires — the delivery package docs say which)
- Install PostgreSQL, or use the provider's managed database to skip backups
ssh root@YOUR_SERVER_IP
# update the system right after connecting
apt update && apt upgrade -yGet the site uploaded and running
Any way up works: git clone is easiest, or zip it locally and upload. For an EazyOPC delivery package, follow START_HERE.md in order: install dependencies, fill in environment variables (things like DATABASE_URL — do them one section at a time, don't paste the whole block), generate the database client, create tables, build, start. Each step has a verification method in the docs — don't skip ahead.
npm install
npx prisma generate
npm run db:push
npm run build
npm startPoint the domain and set up HTTPS
At your domain registrar, point the domain's A record at the server IP and wait minutes to hours for it to take effect. Then install a reverse proxy on the server (Nginx or Caddy) to forward port 80/443 traffic to your site process. HTTPS certificates are all free now — Caddy applies automatically, and Nginx with certbot is just a few commands. This step is done when the browser address bar shows the little lock.
Use pm2 to keep the site always running
npm start got the site running, but there's a fatal problem: close the SSH window and the site dies. Production needs a process manager, and the usual one is pm2. It does three things: runs the site in the background, restarts it when it crashes, and centralizes logs. Installing and using it is not hard:
npm install -g pm2
# start the site with a name you recognize
pm2 start npm --name "my-site" -- start
# view logs / restart / stop
pm2 logs my-site
pm2 restart my-site
pm2 stop my-siteName it something you recognize so you don't mix sites up when several run on one server. When the site has problems, pm2 logs first — the answer is usually in there. After fixing code and redeploying, pm2 restart is enough; no need to kill the process and start it by hand. Remember: anything that “keeps running” should show up in pm2 list. Bare processes will bite you sooner or later.
Make the site come back up by itself after a server reboot
Patching and upgrades reboot servers. After a reboot, pm2-managed sites won't come back up by themselves — unless you do two things. First, run pm2 startup; it gives you a command to copy and execute, which makes pm2 itself start on boot. Second, pm2 save, which saves the current list of running sites. Every time you add or remove a site, run pm2 save again, or the next reboot will bring up the old list and the new site won't start.
How to verify: after setting it up, manually reboot the server once (the provider's console has a reboot button), wait two minutes, and open your site in a browser. It only counts if it opens. Don't wait until the middle of the night when auto-updates reboot the box and you discover the site is down — you'll be asleep and users will already be complaining.
Disk full: the culprit behind slow sites and failed writes
The site gets slow, uploads fail, the database won't write — eight times out of ten the disk is full. Run df -h to see which partition is full, then drill down with du to find what's eating space. The usual three suspects: ever-growing pm2 and nginx log files, accumulating database backup files, and npm cache plus useless packages.
df -h
# find the big directories, drill down level by level
du -sh /var/log/* 2>/dev/null | sort -rh | head
# clear pm2 logs (make sure you have read the errors first)
pm2 flushThe real fix is log rotation: Ubuntu ships logrotate; configure nginx and pm2 logs to rotate daily and keep only 14 days. Keep backup files for only the last 7 days — the cron job from the previous post already auto-deletes old ones. Five minutes with df -h once a month beats being woken up by a full disk at 3am.
Switching servers or reinstalling: the confidence of a 30-minute recovery
Someday you will switch servers: price hikes, datacenter outages, a different region. Whether you can recover in 30 minutes depends on having three things ready ahead of time: code in a git repo (not just sitting on the server), environment variables stored separately (database passwords, payment keys — fill them in after reinstalling), and daily database backups. With those three, a fresh machine is four steps — install environment, pull code, fill variables, import data — done in half an hour. Missing one, and you're in for a whole night.
Where the logs are: look at them first when things break
Three log locations to know: for pm2-managed sites, pm2 logs; nginx or Caddy access and error logs live under /var/log; app-written logs depend on the project config. Read logs bottom-up — the newest is at the bottom; find the first ERROR or stack trace. Don't start from line one; tens of thousands of lines will keep you reading until dawn without finding anything.
Environment variables: don't put them in code
Database passwords, payment keys — those go in a .env file or pm2 environment variables, never hardcoded in code. Two reasons: first, code goes into git, and keys in git are public; second, when you switch servers or rotate a password, you only change the env file, not the code. Keep an encrypted copy of your environment variables separately — if the server dies and you rebuild, fill them back in.
Cron jobs: automate backups and cleanup
Hand two things to cron: back up the database every night (just copy the cron command from the previous post), and clean old logs and backups weekly. Edit with crontab -e, confirm with crontab -l. If a cron job didn't run, first check whether the cron service is running, then look for its execution records in /var/log/syslog. Nobody tells you when a cron job silently dies — regular checking is the only way.
Security group: open only the ports you need
The security group (firewall) opens only 22 (SSH), 80 (HTTP), and 443 (HTTPS) — everything else stays closed. Never expose the database port (5432); the database serves localhost only. Safer SSH: switch to key login and disable password login; or move port 22 to an uncommon number. Being probed and brute-forced is the norm — thousands of login attempts in the logs daily; get used to it, just keep them out.
Swap: the lifesaver for a 1GB box
On a 1GB machine, building projects and running databases often run out of memory. Add a swap partition for emergencies: disk space as memory — slow, but it saves you. Turn swap on for the build, turn it off after. If you're living on swap long-term, you genuinely need more RAM and should upgrade — swap is a band-aid, not a cure.
Install monitoring: know the moment it dies
With the server set up, finally add uptime monitoring: UptimeRobot's free plan checks whether your site loads every 5 minutes and emails you when it's down. The details are in the “Free Tools Roundup for Indie Developers” post. Monitoring is the last piece of operations: everything before it exists so the site stays alive; monitoring is what lets you know first when it dies.