Path B: VPS With rsync
This is a member-only chapter. Log in with your Signal Over Noise membership email to continue.
Log in to readModule 5 · Section 3 of 5
Path B: VPS With rsync
For sites that need more control — a custom nginx configuration, server-side auth, or tools that don’t fit neatly into a serverless model — a VPS is the right call.
I deploy jimchristian.net, signalovernoise.at, sbc.jimchristian.net, howtocodeinminecraft.com, and thinklikeacoder.org to an IONOS VPS. The deploy workflow is rsync over SSH.
What it’s right for: Sites that need custom server config, sites with dynamic server-side logic, situations where you want full control over the environment.
The Deploy Workflow
Build the site locally:
npm run build
Then rsync the dist/ directory to the server:
rsync -avz --delete dist/ deploy@your-vps-ip:/var/www/your-site/
The --delete flag removes files from the server that no longer exist locally — important for keeping the live site in sync with the build output.
A deploy script makes this repeatable:
#!/usr/bin/env bash
set -e
echo "Building..."
npm run build
echo "Deploying..."
rsync -avz --delete dist/ deploy@your-vps-ip:/var/www/your-site/
echo "Done."
Save as deploy.sh, make it executable (chmod +x deploy.sh), and deploy with ./deploy.sh.
nginx Configuration
On the server, nginx serves the static files. A basic config:
server {
listen 80;
server_name your-domain.com;
root /var/www/your-site;
index index.html;
location / {
try_files $uri $uri/ $uri.html =404;
}
}
The try_files directive handles Astro’s clean URLs — it tries the exact path, then a directory index, then the same path with .html appended. This means /about resolves correctly even though the file is about.html.
For SSL, use Certbot with the nginx plugin:
sudo certbot --nginx -d your-domain.com
Certbot modifies the nginx config to add HTTPS and set up automatic renewal. After running it, your site serves on HTTPS.
SSH Key Setup
For the rsync to work, your local SSH key needs to be authorised on the server. Add your public key to ~/.ssh/authorized_keys on the server, or use ssh-copy-id:
ssh-copy-id deploy@your-vps-ip
Store the connection details in your local ~/.ssh/config so you’re not typing IPs:
Host my-vps
HostName your-vps-ip
User deploy
IdentityFile ~/.ssh/id_ed25519
Then your rsync command becomes:
rsync -avz --delete dist/ my-vps:/var/www/your-site/