Who This Guide Is For
- Full-stack developers tired of cloud bills
- Indie hackers launching MVPs
- Anyone who wants full control without complexity
After years of building full-stack applications, I’ve learned that VPS servers offer the perfect balance of control, cost, and simplicity for indie developers and small teams or personal projects. While cloud providers like AWS have their place, a well-configured VPS can handle everything you need, at a fraction of the cost.
I’ve been developing for a long time, since before the cloud hype took over. I’ve always used VPS instead of cloud services. The first cloud I started playing with was AWS, of course, and to be honest, once I finished experimenting, I completely shut everything down. Why? Easy to answer: it’s too expensive for what I really need.
For my personal projects, I’ve always been able to handle a full-stack application in just one place. The only real game-changer in my workflow was Docker, moving from having applications installed at the OS level to running them in containers. This allowed me to have the same version on my local machine and the VPS, making deployments consistent and reliable.
The Real Cost Difference
AWS Equivalent Setup:
- t3.medium instance: ~$30/month
- RDS PostgreSQL: ~$15/month
- Load Balancer: ~$16/month
- Total: ~$61/month
VPS Setup:
- 2 vCPU, 8GB RAM, 100GB NVMe: ~€8-12/month
- Everything included
What You’ll Build
By the end of this guide, you’ll have:
- ✅ A hardened server that’s secure by default
- ✅ Password-less SSH authentication
- ✅ Docker ready for containerized deployments
- ✅ Essential tools for development and monitoring
- ✅ A foundation that can host unlimited projects
What is a VPS
Claude AI definition:
A VPS (Virtual Private Server) is a virtualised server that gives you dedicated resources (CPU, RAM, storage) on a shared physical machine. You get root access and full control, like having your own server, but at a lower cost.
Basically, the VPS is shared resources from a physical device. Normally when you buy the subscription of a VPS, you can see in some of the options that are:
- 2 vCPU cores
- 8 GB RAM
- 100 GB NVMe disk space
- 8 TB bandwidth
But this of course are in a machine Intel Xeon with maybe 64 physical cores 512gb ram and 12 TB of ssd data storate.
How to configure
Normally, depending on the provider, your first access is via SSH with a root password. But of course, it’s not good practice to configure the server under the root user, it’s really dangerous. So we’ll create a user for deployment purposes with sudo permissions.
Initial Access
To access your server:
# ssh@your-server-ip-address
ssh [email protected]
It will ask for your password. Type it and press enter.
Once you’re logged in, the first thing you need to do is upgrade your OS. In my case, I use Ubuntu:
# -y is to accept everything by default
apt update && apt upgrade -y
1. Install Essential Tools
Before continuing, let’s install the essential tools you’ll need:
# Essential development and monitoring tools
sudo apt install -y \
git \
curl \
wget \
htop \
tmux \
unattended-upgrades \
vim
# Optional but useful
sudo apt install -y \
tree \
fail2ban \
Why each tool matters:
- git: Version control for deployment scripts and configurations
- curl/wget: Downloading files and testing APIs
- htop: Better process monitoring than the default
topcommand - tmux: Keep sessions running after you disconnect
- fail2ban: Protects against brute-force SSH attacks, Please reade before about it
- unattended-upgrades: Automatic security updates
- tree: Visualize directory structures
2. Create user
sudo adduser baker # yes, you are now a server baker
- Grant sudo privileges to baker
To give the baker user sudo privileges, add the user to the sudo group:
sudo usermod -aG sudo baker
Verify sudo access works:
sudo -l -U baker
3. Switch to baker user instead root
su baker
4. Add your public ssh key to this user
The purpose of this is to disable password login to the server, only your machines with the correct SSH key will be able to connect.
You need to verify that you’re in the baker home folder, which is /home/baker. Every time you create a user, it creates a home folder for them. To verify which folder you’re in, type pwd, or go directly to your home folder with:
cd /home/baker
# or simply
cd ~
6. Create SSH configuration
6.1 Prepare the directories
mkdir ~/.ssh # to create a directory
chmod 700 ~/.ssh # to give all the permission only to this user
6.2 Create the authorized_keys file
cd ~/.ssh # ~/ this means always that you will be go to your directory is the equivalent to /home/baker
vim authorized_keys # And when you save the file will be created on the directory you are.
In this file, you’ll paste the public key from your local machine.
On your local machine:
- Mac:
/Users/your-username/.ssh - Linux:
/home/your-username/.ssh
In this directory, you should have two files:
ed25519 # Private key (keep this secret!)
# and
ed25519.pub # Public key (this is what you'll copy)
if you don’t have any file is because you never generate them then follow this documentation of github # Generating a new SSH key and adding it to the ssh-agent
6.3 Get the content of the public key
Use cat to show the content of the file, then copy and paste it into the authorized_keys file on your server:
cat ~/.ssh/id_ed25519.pub
Copy the entire output, then on your VPS, paste it into the authorized_keys file:
vim ~/.ssh/authorized_keys
# Press 'i' to enter insert mode
# Paste your public key
# Press 'Esc', then type ':wq' and press Enter to save and exit
Set proper permissions:
chmod 600 ~/.ssh/authorized_keys
No you can logout and enter as baker user 😎
To log out, type exit twice (once for baker, once for root).
7. Configure SSH on your local machine
When you have more than one SSH key or connect to multiple servers, it’s convenient to create an SSH config file on your local machine.
Add your server to your SSH config file
On your local machine, create or edit the SSH config file:
# ~/.ssh/config
# You need to add this
Host myVps
HostName your-vps-ip-OR-domain.com # Normally is the IP addres
User baker # # The user on your VPS
Port 22 # Default SSH port (some change this for extra security)
IdentityFile ~/.ssh/ed25519 # Reference to your private key
IdentitiesOnly yes # Only use this key, don't try others (more secure)
To understand more about how encryption works, you can read this excellent article: Cryptography with Node Crypto Module
8. Connect for the first time with your user
Now that your VPS has your public key, it’s time to test the connection. Open a new terminal on your local machine:
ssh baker@your-vps-ip
# Or, if you created the SSH config:
ssh myVps
You should connect without being asked for a password!
Verify you’re the correct user:
whoami # Should output: baker
sudo whoami # Should output: root (proves sudo works)
9. Disable Password Authentication for Added Security
This is crucial, now that SSH keys work, let’s disable password authentication entirely:
sudo vim /etc/ssh/sshd_config
Find and set the following options to no
PasswordAuthentication no
PermitRootLogin no
Now it is necessary to restart the sshd service
sudo systemctl restart sshd
⚠️ Important: Make sure you can log in with your SSH key before doing this step. Otherwise, you could lock yourself out!
10. Installing Docker
At the moment I’m writing this article, in my opinion, every server needs to have Docker installed. With Docker, you can have multiple apps running without conflicts on your server. You can have different versions of databases for different applications running without any issues—this is just one example of many benefits Docker provides.
To install Docker, you can check the official documentation or follow the commands below. Please check the documentation in case these commands are outdated when you’re reading this.
I just copied and pasted of what at this moment in docker documentation.
- Download certificates and add Docker repository
# Add Docker's official GPG key:
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
- Download certificates and add Docker repository
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- Verify Docker is running
The Docker service starts automatically after installation. To verify:
sudo systemctl status docker
- In case it did not started
sudo systemctl start docker
sudo systemctl enable docker
- Add our user to the Docker group
sudo usermod -aG docker $USER
Activate the group change:
newgrp docker # Activates group without logging out
# OR
exit # Then SSH back in
Verify Docker works without sudo:
docker ps
docker --version
Verification Checklist
Before you start deploying applications, verify everything is working:
# 1. Check you're the correct user
whoami # Should be: baker
# 2. Verify sudo works
sudo whoami # Should be: root
# 3. Check Docker works
docker ps
docker run hello-world
# 4. Check Fail2Ban is running
sudo systemctl status fail2ban
# 5. Verify SSH configuration
cat /etc/ssh/sshd_config | grep PasswordAuthentication
# Should show: PasswordAuthentication no
Interactive VPS shell
Please if you want to do the sepu interactive, you can just download this script from my github repository