How to Secure Your VPS Before Deploying Your Next Side Project

A fresh VPS is not production-ready just because you can SSH into it.
Before deploying your next side project, take a few minutes to lock down the basics. You do not need enterprise security. You do need to avoid the obvious mistakes that bots scan for all day.
Here is a practical checklist.
1. Update the Server
Start with updates:
sudo apt update
sudo apt upgrade -y
Reboot if the kernel was updated:
sudo reboot
Old packages are one of the easiest ways to get owned.
2. Create a Non-Root User
Do not run everything as root.
adduser deploy
usermod -aG sudo deploy
Then SSH as that user and use sudo only when needed.
3. Use SSH Keys, Not Passwords
Copy your public key:
ssh-copy-id deploy@your-server-ip
Then edit SSH config:
sudo nano /etc/ssh/sshd_config
Recommended settings:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
Restart SSH:
sudo systemctl restart ssh
Important: keep your current SSH session open while testing a new one, so you do not lock yourself out.
4. Enable a Firewall
Use UFW for a simple setup:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status
Only expose what you need.
If your app runs on port 3000, keep it bound to 127.0.0.1 and proxy through Nginx instead of exposing it publicly.
5. Install Fail2ban
Fail2ban watches logs and bans repeated bad login attempts.
sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
Check status:
sudo fail2ban-client status
It is not magic, but it helps reduce noise.
6. Keep Apps Behind Nginx
For Node, Nuxt, Laravel, Rails, or similar apps, run the app on localhost and put Nginx in front.
This gives you:
- HTTPS termination
- Better request handling
- Cleaner domain routing
- Logs
- A single public entry point
Your app process should not need to listen directly on the public internet.
7. Add Basic Monitoring
At minimum, know how to check:
systemctl status your-service
journalctl -u your-service -f
df -h
free -m
htop
You do not need a full observability stack for every side project, but you should know when disk, memory, or your app process is failing.
Final Checklist
Before deploying, confirm:
- Packages updated
- Non-root user created
- SSH keys enabled
- Root login disabled
- Password login disabled
- Firewall enabled
- Only ports 22, 80, and 443 open
- App bound to localhost
- Nginx reverse proxy configured
- HTTPS enabled
- systemd service working
Final Thoughts
Security is not a one-time achievement. It is a habit.
But these basics already put you ahead of many rushed deployments. Lock down the server first, then ship the app.
Your future self will thank you when the logs are boring.
