Virtual Private Server
VPS Setup Guide
Initial Server Setup
1. First Connection
ssh root@YOUR_VPS_IP
Accept the fingerprint when prompted.
2. Update System
apt update && apt upgrade -y
3. Create Regular User
adduser yourusername
usermod -aG sudo yourusername
Set a strong password when prompted.
4. Copy SSH Key to New User
rsync --archive --chown=yourusername:yourusername ~/.ssh /home/yourusername
5. Configure Firewall
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
Type y when prompted.
6. Test New User Login
Open a new terminal window (keep root session open):
ssh yourusername@YOUR_VPS_IP
If successful, exit the root session with exit.
Install Node.js and PM2
1. Install Node.js
sudo apt install -y curl
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs
2. Verify Installation
node --version
npm --version
3. Install PM2 (for Node apps)
sudo npm install -g pm2
pm2 startup
Run the command that PM2 outputs.
Install and Configure Nginx
1. Install Nginx
sudo apt install nginx -y
2. Remove Default Site
sudo rm /etc/nginx/sites-enabled/default
3. Configure Node.js App
sudo nano /etc/nginx/sites-available/your-app-name
Paste:
server {
listen 80;
server_name api.yourdomain.com;
location / {
proxy_pass http://localhost:YOUR_APP_PORT;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Replace YOUR_APP_PORT with your app’s port (e.g., 4200).
4. Configure Static Site
sudo nano /etc/nginx/sites-available/your-site-name
Paste:
server {
listen 80;
server_name yourdomain.com;
root /home/yourusername/apps/your-site-name;
index index.html;
include /etc/nginx/mime.types;
default_type application/octet-stream;
location / {
try_files $uri $uri/ /index.html;
}
}
5. Enable Site
sudo ln -s /etc/nginx/sites-available/your-site-name /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
SSL Certificates with Let’s Encrypt
1. Install Certbot
sudo apt install certbot python3-certbot-nginx -y
2. Get Certificate
sudo certbot --nginx -d yourdomain.com
Follow prompts (enter email, agree to terms).
DNS Configuration
For A2 Hosting (Temporary)
- Login to A2 cPanel
- Go to Zone Editor
- Find your domain
- Edit A records for subdomains:
- Name:
subdomain.yourdomain.com - Type: A
- Address: Your VPS IP
- Name:
For Namecheap (When Ready to Migrate)
- Login to Namecheap
- Domain List → Manage
- Switch from custom nameservers to Namecheap BasicDNS
- Advanced DNS tab
- Add A Record:
- Host:
@(root) or subdomain name - Type: A
- Value: Your VPS IP
- TTL: Automatic
- Host:
Project Directory Structure
/home/yourusername/
apps/
app1-name/ # Node.js apps and static sites
app2-name/
site1-name/
Fix Permissions (If Needed)
chown -R yourusername:yourusername ~/apps/project-name
chmod -R 755 ~/apps/project-name
find ~/apps/project-name -type f -exec chmod 644 {} \;
Useful Commands
PM2 Management
pm2 list # List all processes
pm2 logs app-name # View logs
pm2 restart app-name # Restart app
pm2 stop app-name # Stop app
pm2 delete app-name # Remove from PM2
pm2 save # Save current process list
Nginx Management
sudo nginx -t # Test configuration
sudo systemctl reload nginx # Apply config changes
sudo systemctl restart nginx # Full restart
sudo tail -f /var/log/nginx/error.log # View error log
System Management
sudo apt update && sudo apt upgrade -y # Update system
sudo reboot # Restart server
df -h # Check disk space
htop # View processes (install with: sudo apt install htop)
File Transfer
Use FileZilla (SFTP):
- Protocol: SFTP
- Host: Your VPS IP
- Port: 22
- User: Your username
- Key file: Your local SSH private key (~/.ssh/id_rsa)
Environment Variables
Create .env.production in your app directory:
cd ~/apps/your-app-name
nano .env.production
Add your variables, save with Ctrl+X, Y, Enter.
The deploy script excludes .env* files from being overwritten.
Troubleshooting
502 Bad Gateway (Node apps)
- Check if app is running:
pm2 list - Check app logs:
pm2 logs app-name - Verify port in Nginx config matches app port
500 Internal Server Error (Static sites)
- Check Nginx error log:
sudo tail /var/log/nginx/error.log - Verify file permissions:
ls -la ~/apps/site-name - Fix permissions if needed (see commands above)
Can’t SSH
- Verify firewall allows port 22:
sudo ufw status - Check SSH service:
sudo systemctl status ssh
DNS Not Propagating
- Check with:
dig yourdomain.com +short - Wait 5-60 minutes for propagation
- Clear local DNS cache if needed
Learning Lab Notes