Created
September 26, 2025 20:23
-
-
Save bkanhu/8c60a20e7007a1a9c22afd0445779395 to your computer and use it in GitHub Desktop.
Setup VPS for MERN stack deployment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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