Skip to content

Instantly share code, notes, and snippets.

@bkanhu
Created September 26, 2025 20:23
Show Gist options
  • Select an option

  • Save bkanhu/8c60a20e7007a1a9c22afd0445779395 to your computer and use it in GitHub Desktop.

Select an option

Save bkanhu/8c60a20e7007a1a9c22afd0445779395 to your computer and use it in GitHub Desktop.
Setup VPS for MERN stack deployment.
# 1. Create deployer User (from root)
adduser deployer
usermod -aG sudo deployer
# This:
# - Creates a new user deployer
# - Adds them to the sudo group (but we'll limit what they can actually do)
# 2. Set Up SSH Access for deployer
# Switch user to deployer
sudo su - deployer
# Create the .ssh directory and set correct permissions
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# Generate an SSH key pair (on your local machine — NOT on the server)
# On your local computer, open a terminal and run:
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# - When asked where to save the key, just press Enter to accept the default (~/.ssh/id_rsa).
# - When asked for a passphrase, you can leave it empty or add one.
# Copy the public key to the server for the deployer user
# Run this command from your local machine (replace your-server-ip):
ssh-copy-id deployer@your-server-ip
#This will copy your public key to the server and add it to ~deployer/.ssh/authorized_keys.
# Test SSH login
# From your local machine, try to login:
ssh deployer@your-server-ip
# 3. Limit What deployer Can Run with sudo
# We don’t want full sudo access — just what’s needed for deployment.
sudo visudo
# Then add at the end:
deployer ALL=(ALL) NOPASSWD: /usr/bin/systemctl, /usr/sbin/nginx, /usr/sbin/nginx -t, /usr/bin/certbot, /bin/ln, /usr/bin/tee, /usr/bin/mkdir, /bin/chown, /bin/chmod
# This lets deployer run:
# - NGINX reload / test
# - Certbot for SSL
# - Create folders and write files to system locations
# - ✅ No password needed, but access is restricted only to these safe commands.
#!/bin/bash
# -----------------------------
# Usage:
# ./setup-client.sh client.com frontend-repo admin-repo api-repo
# -----------------------------
# 📥 Input params
DOMAIN=$1
FRONTEND_REPO=$2
ADMIN_REPO=$3
API_REPO=$4
# 📁 Directory structure
BASE_DIR="/var/www/$DOMAIN"
FRONTEND_DIR="$BASE_DIR/frontend"
ADMIN_DIR="$BASE_DIR/admin"
API_DIR="$BASE_DIR/api"
# 🔧 App ports
FRONTEND_PORT=3000
ADMIN_PORT=3001
API_PORT=3002
# 🧱 Create project folders and set permissions
echo "📁 Creating project structure at $BASE_DIR"
sudo mkdir -p $FRONTEND_DIR $ADMIN_DIR $API_DIR
sudo chown -R deployer:deployer $BASE_DIR
sudo chmod -R 750 $BASE_DIR
# ⬇️ Clone projects
echo "🔽 Cloning repos..."
sudo -u deployer git clone $FRONTEND_REPO $FRONTEND_DIR
sudo -u deployer git clone $ADMIN_REPO $ADMIN_DIR
sudo -u deployer git clone $API_REPO $API_DIR
# 📦 Install dependencies
echo "📦 Installing npm dependencies..."
cd $FRONTEND_DIR && sudo -u deployer npm install
cd $ADMIN_DIR && sudo -u deployer npm install
cd $API_DIR && sudo -u deployer npm install
# 🚀 Start apps with PM2
echo "🚀 Starting apps with PM2..."
sudo -u deployer pm2 start $FRONTEND_DIR/ecosystem.config.js --name "$DOMAIN-frontend"
sudo -u deployer pm2 start $ADMIN_DIR/ecosystem.config.js --name "$DOMAIN-admin"
sudo -u deployer pm2 start $API_DIR/ecosystem.config.js --name "$DOMAIN-api"
# 🔧 Generate NGINX configs
echo "🔧 Creating NGINX configs..."
# Frontend - client.com
sudo tee /etc/nginx/sites-available/$DOMAIN > /dev/null <<EOF
server {
listen 80;
server_name $DOMAIN;
location / {
proxy_pass http://localhost:$FRONTEND_PORT;
include proxy_params;
proxy_redirect off;
}
}
EOF
# Admin - admin.client.com
sudo tee /etc/nginx/sites-available/admin.$DOMAIN > /dev/null <<EOF
server {
listen 80;
server_name admin.$DOMAIN;
location / {
proxy_pass http://localhost:$ADMIN_PORT;
include proxy_params;
proxy_redirect off;
}
}
EOF
# API - api.client.com
sudo tee /etc/nginx/sites-available/api.$DOMAIN > /dev/null <<EOF
server {
listen 80;
server_name api.$DOMAIN;
location / {
proxy_pass http://localhost:$API_PORT;
include proxy_params;
proxy_redirect off;
}
}
EOF
# 🔗 Enable NGINX configs
echo "🔗 Linking NGINX configs..."
sudo ln -sf /etc/nginx/sites-available/$DOMAIN /etc/nginx/sites-enabled/
sudo ln -sf /etc/nginx/sites-available/admin.$DOMAIN /etc/nginx/sites-enabled/
sudo ln -sf /etc/nginx/sites-available/api.$DOMAIN /etc/nginx/sites-enabled/
# 🔄 Reload NGINX
echo "🔄 Reloading NGINX..."
sudo nginx -t && sudo systemctl reload nginx
# 🔒 Get SSL certificates for all domains
echo "🔐 Requesting SSL certificates for:"
echo " - $DOMAIN"
echo " - admin.$DOMAIN"
echo " - api.$DOMAIN"
sudo certbot --nginx -d $DOMAIN -d admin.$DOMAIN -d api.$DOMAIN --non-interactive --agree-tos -m you@example.com
echo "✅ Done! $DOMAIN apps are deployed and secured."
# USAGE: ./setup-client.sh client.com frontend-repo admin-repo api-repo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment