Phase 1: Bare Linux VPS Setup, Sudo & SSH Hardening
When provisioning a fresh virtual server, the first priority is establishing system baseline metrics, creating a dedicated non-root administrative account, and hardening SSH to eliminate password brute-force and root-login attack vectors.
root? It saves me typing sudo before every single command!"
root user has UID 0 and bypasses all filesystem permissions without warnings. A simple typo like rm -rf / tmp could destroy your entire OS in a fraction of a second. By creating a dedicated user (firoz) and granting sudo rights, every privileged execution is conscious, logged in /var/log/auth.log, and separated by privilege boundaries."
1.1 System Inspection & User Creation
We inspect available memory with free -h (~7.7 GiB RAM), disk space with df -h / (96 GiB), and CPU cores with nproc (2 vCPUs). We then create a standard admin user and add them to the sudoers group.
1.2 SSH Hardening & Strict Permissions
We copy the public SSH key to /home/firoz/.ssh/authorized_keys with strict permissions (700 dir, 600 file), and create a modular hardening config in /etc/ssh/sshd_config.d/00-hardening.conf.
sudo sshd -t, verify effective rules with sudo sshd -T, and open a NEW, separate terminal window to test ssh firoz@200.234.43.151 before terminating your session.
1.3 UFW Firewall Activation
Linux iptables/netfilter is managed cleanly via UFW (Uncomplicated Firewall). We enforce a strict default deny incoming policy, allow outbound connections, and explicitly whitelist TCP port 22 for SSH.
Phase 2: Networking, Nginx Web Server, DNS & HTTPS
In Phase 2, we turn the VPS into an internet-facing web server. We explore Linux networking, understand socket binding (localhost vs 0.0.0.0), configure Nginx Virtual Hosts, point real DNS records, and secure traffic with automated Let's Encrypt TLS certificates.
sites-available and sites-enabled directories? Why not just put all configuration files in one single folder?"
sites-available as your configuration vault containing all website blueprints. sites-enabled contains only the active websites. By creating a symbolic link (symlink) from sites-available/mysite into sites-enabled/, you can enable or disable a site in 1 second with rm without deleting or modifying your original configuration!"
2.1 Deep Dive: How Symbolic Links (Symlinks) Work in Linux
A symlink (soft link) is a special file whose content is a textual path pointing to another file's inode on the filesystem. When Nginx reads /etc/nginx/sites-enabled/learning-site, the Linux kernel automatically resolves the pointer to /etc/nginx/sites-available/learning-site.
2.2 DNS Configuration & Name Resolution
DNS maps human-readable domain names to numerical IP addresses. We configured:
- A Record: @ (firozjaroli.tech) -> 200.234.43.151
- CNAME: www -> firozjaroli.tech
- A Record: api -> 200.234.43.151 (for Spring Boot API)
2.3 HTTPS & Let's Encrypt TLS Automation
Certbot interacts with Let's Encrypt via the ACME HTTP-01 challenge, automatically installs SSL certificates, updates Nginx server blocks, and sets up 301 HTTP-to-HTTPS redirects.
Phase 3: Spring Boot Deployment, systemd & Reverse Proxying
In Phase 3, we build and package a real Java 21 Spring Boot executable JAR, deploy it to /opt/devops-learning/, manage its lifecycle as a resilient background service using systemd, bind it strictly to 127.0.0.1 for security isolation, and expose it through Nginx as a reverse proxy under api.firozjaroli.tech.
127.0.0.1 instead of letting it listen on 0.0.0.0? And why do we need Nginx in front of it?"
127.0.0.1 guarantees that Spring Boot is completely invisible to the external internet. Only processes inside the VPS can connect to it. Nginx acts as our secure front door: it terminates TLS encryption, handles rate limiting, caches static assets, and proxies sanitized HTTP requests internally to Spring Boot. If an attacker scans your server, they cannot attack Tomcat directly!"
3.1 Anatomy of a Production systemd Unit File
Running java -jar in a terminal is fragile because closing the SSH session kills the process. We create /etc/systemd/system/devops-learning.service to give the JVM supervision, automatic crash restart, and boot persistence.
3.2 Nginx Reverse Proxy Configuration (devops-api)
We configure /etc/nginx/sites-available/devops-api to intercept requests for api.firozjaroli.tech and proxy them over localhost with forwarded client headers.
Phase 4: Production Ops, Blue-Green Deployments, Graceful Shutdown & Backups
Phase 4 elevates our server to true enterprise operational standards: implementing health check telemetry, versioned artifact storage, zero-downtime atomic symlink switching, SIGTERM graceful shutdown handling, fixed-environment Blue-Green deployments, and automated compressed disaster recovery backups.
4.1 Versioned Releases & Atomic Switching
Never overwrite devops-learning.jar directly in production! Instead, store immutable artifacts in releases/ and atomically update symlinks with ln -sfn.
4.2 Graceful Shutdown & Exit Status 143
Spring Boot configured with server.shutdown=graceful catches SIGTERM (Signal 15) from systemd, stops accepting new connections, drains active in-flight HTTP requests, and exits cleanly with code 143 ($128 + 15 = 143$).
4.3 Fixed-Environment Blue-Green Deployment Pattern
4.4 Backups & Disaster Recovery (The 3-2-1 Rule)
We measured our total deployment footprint (/opt ~57M, /etc/nginx ~96K, systemd ~12K) and created compressed tar archives.
Interactive Network Request Path Tracer
Trace an HTTPS request from the user's browser all the way to Spring Boot's internal Tomcat thread pool.
Live Blue-Green Deployment Simulator
Simulate switching live traffic, testing standby health checks, and executing zero-downtime rollbacks.
Symlink & Inode Pointer Workbench
See how Linux symbolic links repoint target binaries atomically in memory without touching running services.
/opt/devops-learning/releases/
/opt/devops-learning/current.jar
The systemd service unit executes current.jar. When releasing or rolling back, we simply update this link using ln -sfn.
Interactive Production Debugging Assistant
Select an incident scenario below to walk through the exact 5-layer diagnostic triage procedure.
Core DevOps Architectural Comparisons
Clarifying nuances, common misconceptions, and design tradeoffs encountered across the 4 phases.
📁 /etc/nginx/sites-available vs /etc/nginx/sites-enabled
Contains the master source configuration files for all virtual hosts. Nginx does NOT read this directory automatically. It acts as an archive and recipe storage.
Contains symbolic links pointing back to files in sites-available/. Nginx includes this directory via include /etc/nginx/sites-enabled/*;. Only symlinked files are loaded into memory.
🗂️ Linux Standard Filesystem Hierarchy in Production
/var/log/nginx), static web assets (/var/www).
~/.ssh/authorized_keys), user backups.
/usr/bin/java), shared libraries, and documentation.
⚡ systemctl reload vs systemctl restart
Instructs the running master process to re-parse configuration files without killing active connections. Old workers drain their current requests while new workers handle fresh traffic.
Terminates the process completely and boots a fresh instance. Brief downtime occurs for in-flight requests during socket binding.
🌐 Sockets: 127.0.0.1 vs 0.0.0.0 vs Public IP
DevOps Architecture & Operations Quiz
Test your mastery of Linux, Nginx, reverse proxies, and Blue-Green zero-downtime deployments.