Case Study

End-to-End Deployment of Guidra Backend on Azure VM

Azure VM → Nginx → Node.js → MongoDB Atlas

Executive Summary

This case study documents the production deployment of the Guidra backend API on Microsoft Azure infrastructure. The implementation demonstrates production-oriented deployment practices including security hardening, reverse proxy configuration, SSL termination, process management, and cloud database integration.

Technologies Used: Azure VM (Ubuntu 24.04), Nginx, Node.js, PM2, MongoDB Atlas, Let's Encrypt

Key Metrics:

  • API latency: ~150–230ms
  • Memory usage: ~600MB (idle)
  • Uptime tested: 7+ days
  • SSL rating: A (Qualys SSL Labs)
  • Deployment time: less than 30 seconds (automated script)
  • Availability: 24/7 production uptime

1. System Architecture

Internet → Azure NSG → UFW → Nginx (reverse proxy) → PM2 → Node.js App → MongoDB Atlas
LayerTechnologyPurpose
CloudAzure VM (B2als v2)Compute infrastructure
NetworkAzure NSG + UFWDefense-in-depth firewall
Web ServerNginxReverse proxy, SSL termination
RuntimeNode.js 20 LTSApplication execution
ProcessPM2Process management, auto-restart
DatabaseMongoDB AtlasCloud database service
Securityfail2ban, SSH hardeningIntrusion prevention
SSLLet's EncryptFree automated certificates

2. Deployment Phases

Infrastructure Foundation

  • Azure VM provisioning with static public IP
  • SSH key authentication (password-less)
  • Deploy user creation (non-root)
  • UFW configuration (ports 22, 80, 443 only)

Security Implementation

  • SSH hardening (/etc/ssh/sshd_config modifications)
  • fail2ban configuration with custom jail
  • Automatic security updates enabled
  • Azure NSG rules configured

Application Stack

  • NVM + Node.js LTS installation
  • PM2 process manager setup
  • MongoDB Atlas connection with SRV string
  • Environment variable management

Web Server Configuration

  • Nginx reverse proxy setup
  • SSL certificates via Let's Encrypt
  • HTTP → HTTPS redirection
  • Custom domain configuration

Deployment Automation

  • Git-based deployment script
  • SSH config for GitHub authentication

3. Challenges & Solutions

ChallengeSolutionEngineering Impact
SSH lockout during fail2ban testingAzure portal emergency SSH key resetUnderstood cloud recovery paths
Nginx only listening on IPv6Added listen 0.0.0.0:80; directiveLearned socket binding nuances
Domain DNS propagation delayUsed dnschecker.org for verificationReal-world DNS debugging
Azure NSG blocking port 80Added inbound rule in portalCloud firewall configuration
GitHub SSH key confusionCreated ~/.ssh/config with explicit IdentityFileSSH client mastery
fail2ban config overwrite riskUsed jail.local instead of modifying jail.confConfiguration best practices

Key Incident: Self-inflicted SSH ban led to Azure emergency recovery—validated both fail2ban functionality and cloud provider fallback mechanisms.

4. Security Hardening

Defense in Depth Implementation

LayerTechnologyConfiguration
Network EdgeAzure NSGInbound rules: 22,80,443 only
Host FirewallUFWDefault deny, explicit allow
Intrusion Preventionfail2ban3 strikes → 1 hour ban
Access ControlSSHKeys only, root disabled
Updatesunattended-upgradesAutomatic security patches
EncryptionLet's Encrypt90-day certs, auto-renewal

SSH Hardening Parameters

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
AllowUsers deploy

fail2ban Configuration

[sshd]
enabled = true
maxretry = 3
bantime = 3600
findtime = 600

5. Production Validation

Tests Performed

TestMethodResult
Server reboot persistencesudo reboot followed by SSH✅ PM2 auto-restart verified
Process crash recoverykill -9 <node-pid>✅ PM2 respawned within 2s
Nginx auto-startServer reboot check✅ Nginx active post-reboot
SSL auto-renewalcertbot renew --dry-run✅ Successful
Firewall rulesnmap -p 22,80,443 from external✅ Only specified ports open
DNS resolutiondig guidra.tech✅ Correct A record
Reverse proxyDirect port 3000 vs 443✅ Headers preserved
Health endpointContinuous monitoring✅ 200 OK response

Logging Infrastructure

/var/www/guidra/logs/      # Application logs (out/err/combined)
/var/log/nginx/            # Web server access/error logs
/var/log/fail2ban.log      # Intrusion attempts
/var/log/auth.log          # Authentication events

6. Deployment Workflow

Simple, Reliable Deployment

# Local development
git add .
git commit -m "feature update"
git push

# Server deployment (single command)
ssh deploy@guidra.tech './deploy-guidra.sh'

Deploy Script Logic

cd /var/www/guidra/current
git pull
npm ci --only=production || npm install --production
pm2 restart guidra-api --update-env

CI/CD Philosophy: Manual trigger with automation—balance of control and efficiency for solo development.

Deployment is triggered manually from the local machine using SSH and a deployment script.

7. Key Lessons & Engineering Insights

Technical Mastery Gained

  • Network layering: NSG vs UFW vs application-level filtering
  • DNS mechanics: Propagation, TTL, record types
  • Socket binding: localhost vs 0.0.0.0 implications
  • Process management: PM2's role in production reliability
  • Configuration management: Never edit original config files

Operational Wisdom

  • Always test security features with backup access
  • Document recovery procedures before needing them
  • Monitor logs before monitoring metrics
  • Simple automation beats complex tooling
"The day I banned myself from my own server taught me more about fail2ban, Azure recovery, and SSH than any tutorial could."

8. Future Improvements

PriorityImprovementRationale
HighAutomated backups to S3Data durability
HighRate limiting implementationAPI abuse prevention
MediumPM2 monitoring dashboardVisual metrics
MediumGitHub Actions CI/CDFully automated deploys
LowDocker containerizationEnvironment consistency
LowMulti-instance scalingHorizontal scalability

Live System

9. Conclusion

This deployment transformed a fresh Azure VM into a production-tested backend deployment hosting the Guidra API. The implementation encompasses security hardening, reverse proxy configuration, SSL termination, process management, and cloud database integration—all providing a reliable and maintainable production environment.

The experience provided invaluable hands-on learning in system administration, networking, and DevOps that textbooks cannot replicate. From recovering from self-inflicted SSH bans to debugging Nginx listen directives, each challenge reinforced practical engineering skills.

The experience provided hands-on learning in system administration, networking, and DevOps beyond textbook environments.

Engineering Competencies Demonstrated

  • Linux System Administration
  • Cloud Infrastructure (Azure)
  • Network Security (NSG, UFW, fail2ban)
  • Web Server Configuration (Nginx)
  • Process Management (PM2)
  • Database Integration (MongoDB Atlas)
  • SSL/TLS Implementation
  • DNS Configuration
  • Deployment Automation
  • Incident Recovery