Introduction
Tired of paying $10-50/month for hosting simple APIs? I was running a Node.js/Express server for my wife's photography business Stripe payments on my Windows machineβwhich meant it only worked when my PC was on. Cloud hosting felt like overkill for a simple payment endpoint processing 10-20 transactions monthly.
Enter the Raspberry Pi 3 B+ β $100 of hardware (complete kit) that runs 24/7 for about $2/year in electricity. In this guide, I'll show you exactly how I migrated my production server to a Pi using Tailscale for secure remote access.
Why a Raspberry Pi for Production?
Cost Breakdown:
My Use Case:
Perfect fit for a Pi.
What You'll Need
Hardware: CanaKit Raspberry Pi 3 B+ Starter Kit ($99.99)
I used the CanaKit Raspberry Pi 3 B+ Starter Kit which includes everything:
What's in the box:
Why this kit?
Software (All Free)
Step 1: Initial Raspberry Pi Setup (10 Minutes)
Unbox and Assemble
1. Install heat sinks on the CPU and RAM chips 2. Insert microSD card (comes pre-loaded with Raspberry Pi OS) 3. Snap Pi into the case 4. Connect HDMI, keyboard, mouse 5. Plug in power via the PiSwitch
First Boot Configuration
The Pi will boot into the setup wizard:
1. Set your country/timezone 2. Change default password (important!) 3. Connect to WiFi (or use ethernet) 4. Update software (takes ~10 minutes) 5. Reboot
Enable SSH for Headless Access
# Open Raspberry Pi Configuration
sudo raspi-configNavigate to: Interface Options β SSH β Enable
Reboot
sudo reboot
Find your Pi's IP address:
hostname -I
Now you can SSH from your laptop:
ssh pi@192.168.1.XXX
Step 2: Install Node.js and PM2
Install Node.js (v18 LTS)
# Update system packages
sudo apt update && sudo apt upgrade -yInstall Node.js from NodeSource
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejsVerify installation
node -v # Should show v18.x.x
npm -v # Should show 9.x.x
Install PM2 Process Manager
PM2 keeps your Node.js app running 24/7, auto-restarts on crashes, and survives reboots.
# Install PM2 globally
sudo npm install -g pm2Verify
pm2 -v
Step 3: Transfer Your Server Files
I transferred my files from Windows using SCP. You have several options:
Option A: SCP from Windows/Mac/Linux
# From your development machine
scp -r /path/to/your/server pi@192.168.1.XXX:/home/pi/
Option B: WinSCP (Windows GUI)
1. Download WinSCP 2. Connect to pi@YOUR_PI_IP 3. Drag and drop your server folder
Option C: Git Clone
If your project is in GitHub:
# On the Pi
cd /home/pi
git clone https://github.com/yourusername/your-server.git
cd your-server
My server structure:
/home/pi/stripe-server/
βββ index.js
βββ package.json
βββ package-lock.json
βββ .env
βββ node_modules/ (will install on Pi)
Step 4: Install Dependencies and Start Server
# Navigate to your server directory
cd /home/pi/stripe-serverInstall dependencies
npm installTest run (should work locally)
node index.jsIf it works, stop it (Ctrl+C) and start with PM2
pm2 start index.js --name "stripe-server"Check status
pm2 statusView logs
pm2 logs stripe-serverMake it survive reboots
pm2 startup
pm2 save
PM2 Startup Output: PM2 will give you a command to run. Execute it:
sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u pi --hp /home/pi
Now your server starts automatically when the Pi boots!
Step 5: Secure Remote Access with Tailscale
This is where the magic happens. Instead of opening ports and dealing with dynamic DNS, Tailscale creates a secure mesh network.
Install Tailscale on the Pi
# Install Tailscale
curl -fsSL https://tailscale.com/install.sh | shAuthenticate and connect
sudo tailscale up
This will give you a URL to authorize the device. Open it in your browser and log in with Google/GitHub/etc.
Get Your Tailscale IP
tailscale ip -4
You'll get something like xxx.78.xxx.13. This is your Pi's permanent Tailscale IP.
Test Local Access
From another device on your Tailscale network:
curl http://xxx.78.xxx.13:3000
Enable Tailscale Funnel (Public Access)
Funnel makes your server publicly accessible via HTTPS without exposing your home IP:
# Enable funnel on port 3000
tailscale funnel 3000
Your server is now available at:
https://raspberry.tailXXXX.ts.net
Security Note: Only enable funnel if you need public access. For internal tools, just use the Tailscale IP.
Step 6: Update Your Frontend
Update your Angular/React/whatever frontend to point to the new URL:
Before:
const API_URL = 'http://localhost:3000';
After:
const API_URL = 'https://raspberry.taila561.ts.net';
Or use the Tailscale IP if accessing from within your network:
const API_URL = 'http://xxx.78.xxx.13:3000';
Real-World Performance
After running this setup for several weeks:
Response Times
Resource Usage
# Check resource usage
htop
My Stripe server:
Power Consumption
Compare to AWS Lightsail $10/month instance: $120/year saved.
Monitoring & Maintenance
PM2 Commands
# Check server status
pm2 statusView real-time logs
pm2 logs stripe-serverRestart server
pm2 restart stripe-serverStop server
pm2 stop stripe-serverView resource usage
pm2 monit
System Monitoring
# Check CPU temperature
vcgencmd measure_tempCheck system resources
htopCheck disk space
df -hView system logs
sudo journalctl -xe
Auto-Updates
Set up unattended-upgrades for security:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
Production Considerations
What Works Great on a Pi
β Low-traffic APIs (< 1,000 requests/day) β Webhook handlers (Stripe, GitHub, etc.) β Scheduled jobs/cron tasks β Internal tools and dashboards β Development/staging environments β IoT/home automation backends
What Doesn't Work Well
β High CPU workloads (video encoding, ML training) β Heavy database operations (large PostgreSQL queries) β Memory-intensive apps (limited to 1GB RAM) β Mission-critical services (no redundancy) β High-traffic production (1000+ concurrent users)
My Recommendation
Use the Pi for:
For high-traffic or mission-critical stuff, stick with proper cloud hosting.
Backup Strategy
My backup approach:
1. Code: Always in Git (GitHub private repo) 2. Database: Daily dump to Tailscale-connected NAS 3. SD card image: Monthly full backup
# Backup script (save as backup.sh)
#!/bin/bash
DATE=$(date +%Y-%m-%d)
tar -czf ~/backups/server-$DATE.tar.gz ~/stripe-server
Run it with cron:
crontab -e
Add this line:
0 2 * ~/backup.sh
Cost Analysis: 1-Year Total Cost of Ownership
Raspberry Pi Setup
Cloud Hosting Alternative
Break-even with cheapest cloud option: 2-3 months 5-year savings vs DigitalOcean: $350
Troubleshooting
Server won't start after reboot
# Check PM2 status
pm2 statusReinstall PM2 startup
pm2 unstartup
pm2 startup
pm2 save
Can't access via Tailscale
# Check Tailscale status
tailscale statusRestart Tailscale
sudo systemctl restart tailscaled
High CPU temperature (> 80Β°C)
# Check temperature vcgencmd measure_tempThe heat sinks should keep it under 70Β°C
If higher, ensure case ventilation is good
Out of disk space
# Check space
df -hClean up logs
sudo journalctl --vacuum-time=7dClean npm cache
npm cache clean --force
Next Steps
Once you're comfortable with this setup, consider:
1. Add SSL certificate (if not using Tailscale funnel) 2. Set up monitoring (Prometheus + Grafana) 3. Add a second Pi for redundancy 4. Run multiple services (add Nginx reverse proxy) 5. Dockerize your apps for easier management
Conclusion
Running a production Node.js server on a Raspberry Pi 3 B+ is:
The CanaKit Raspberry Pi 3 B+ Starter Kit at $99.99 gives you everything you need in one package. No hunting for compatible parts, no surprises.
My Stripe payment server has been running flawlessly for weeks, costing me pennies while saving $10-25/month in cloud hosting fees.
If you're running simple services that don't need enterprise-grade infrastructure, give the Pi a shot. Worst case, you're out $100 and learned a lot about Linux system administration. Best case, you save hundreds per year and gain complete control over your infrastructure.
---
Questions or running into issues? Drop a comment below or reach out on LinkedIn.
Affiliate Disclosure: The Amazon link above is an affiliate link. If you purchase through it, I earn a small commission at no extra cost to you. It helps support this blog!
Related Posts
Building with Angular + Firebase? Check out my Photography E-Commerce Platform that combines Firebase auth with Stripe payments and AWS S3 storage.
Self-hosting your projects? Learn how I host production apps on a Raspberry Pi with PM2, Nginx, and Tailscale.
About the Author: Ricardo Gil is a full-stack software engineer specializing in .NET/C#, Angular, and cloud platforms. Read more or subscribe for updates.
