How a Website Actually Works β€” The Garden’s Journey

Ever type a URL and wonder what really happens? Let’s follow your browser’s journey when you visit https://garden.christianjeremia.com β€” explained like you’re five. πŸ§’


The Big Picture

You type: garden.christianjeremia.com

    β‘   Phone Book (DNS)
    β‘‘  Security Check (SSL)
    β‘’  The Doorman (Caddy)
    β‘£  The Server (Nginx)
    β‘€  The House (VPS)

You see: A beautiful garden page 🌻

Each step has a job. Let’s dive into each one.


β‘  DNS β€” The Phone Book of the Internet ☎️

What is it?

DNS stands for Domain Name System. Think of it as the phone book of the internet.

Real worldInternet world
You want to call β€œPizza Hut”You want to visit β€œgarden.christianjeremia.com”
You look up their numberYour computer looks up their IP address
You dial the numberYour browser connects to the IP address
”Hello, Pizza Hut!""Hello, server!”

Every computer on the internet has a number (IP address) like 43.133.130.60. But humans are bad at remembering numbers β€” we’re good at remembering names like garden.christianjeremia.com. DNS is the system that translates names to numbers.

How it happens (simplified)

Your browser: "Where is garden.christianjeremia.com?"
     ↓
Your phone/ISP: "Let me ask the internet phone book..."
     ↓
Cloudflare (our DNS provider): "It's at 43.133.130.60"
     ↓
Your browser: "Got it! Now I'll visit 43.133.130.60"

Who pays for this?

Nobody! DNS is free. You pay for the domain name (christianjeremia.com) β€” about $7.85/year to Cloudflare β€” and they give you free DNS management.

Why Cloudflare DNS?

Cloudflare is our phone book operator. When you bought christianjeremia.com, Cloudflare said β€œgreat, you can manage all the subdomains here”:

SubdomainWhat it points to
garden.christianjeremia.com→ Your VPS (IP: 43.133.130.60)
christianjeremia.com→ Vercel (portfolio)

β‘‘ SSL β€” The Security Guard πŸ”’

What is it?

SSL stands for Secure Sockets Layer (okay, actually it’s TLS now, but everyone says SSL). It’s the padlock πŸ”’ you see in your browser bar.

What does it do?

Two things:

  1. Encryption β€” Scrambles the data so no one can read it
  2. Identity proof β€” Proves the website is who it says it is

Without SSL

You: "Hi, I want to read the garden!"
     ↓
Hacker: "I'm the garden, trust me! Here's a fake page."
     ↓
You: "Looks real enough..." 😱 (hacker steals your data)

With SSL

You: "Hi, I want to read the garden!"
     ↓
Garden: "Here's my ID card signed by Cloudflare. 
         You can trust me. Let's speak in secret code."
     ↓
You & Garden: Chat in encrypted language that only you two understand 🀝

How Cloudflare handles it for us

In our setup, Cloudflare does the SSL work. The conversation goes:

You ──HTTPS (encrypted)──→ Cloudflare ──HTTP (plain)──→ Your VPS

Your browser talks to Cloudflare securely. Cloudflare talks to your VPS in plain HTTP. This is called SSL Termination β€” Cloudflare handles the hard crypto work so your VPS doesn’t have to.

We set Cloudflare to Flexible mode, which means:

  • βœ… You get the green padlock
  • βœ… Your VPS doesn’t need to handle SSL
  • ⚠️ The last mile (Cloudflare β†’ VPS) is unencrypted (but it’s fine for a static garden with no passwords!)

β‘’ Caddy β€” The Doorman πŸšͺ

What is it?

Caddy is a reverse proxy. Fancy term. But really, it’s a doorman for your server.

Analogy: An Apartment Building

Imagine your VPS is an apartment building at 43.133.130.60:

43.133.130.60 (Apartment Building)
β”œβ”€β”€ πŸšͺ Door 8080 β†’ πŸ—οΈ Nginx lives here (the gardener)
└── πŸšͺ Door 80   β†’ πŸšͺ Caddy lives here (the doorman)

Without Caddy, visitors would have to know the specific door number: http://43.133.130.60:8080. Ugly, right?

Caddy stands at Door 80 (the main entrance) and says:

Visitor at Door 80: "I'm here for the garden!"
Caddy: "Ah, garden.christianjeremia.com! Let me send you to 
        Room 8080 where Nginx is."

Visitor at Door 80: "I'm here for /"
Caddy: "The garden's entrance is at /notes/index. Follow me!"
Caddy sends them to: /notes/index (clean, no port number!)

What Caddy solves

Before CaddyAfter Caddy
http://43.133.130.60:8080https://garden.christianjeremia.com
Port :8080 visible in URLNo port visible
Ugly redirect: http://...:8080/notes/indexClean redirect: /notes/index
Direct IP accessDomain-based routing

Caddy’s actual config

http://garden.christianjeremia.com {
    redir / /notes/index 301
    reverse_proxy localhost:8080
}

Translation:

  • β€œWhen someone visits garden.christianjeremia.com/, tell them to go to /notes/index instead”
  • β€œFor everything else, hand it off to the program at localhost:8080 (which is Nginx)β€œ

β‘£ Nginx β€” The Server πŸ—οΈ

What is it?

Nginx (pronounced β€œEngine-X”) is a web server. It’s the actual librarian that finds the right book (file) and hands it to the visitor.

Analogy: A Library

Visitor: "I want to read /notes/what-is-nginx"
     ↓
Caddy (doorman): "Go to room 8080, Nginx will help you"
     ↓
Nginx (librarian): "Let me find that book..."

Nginx looks:
  1. Is there a file called `/notes/what-is-nginx`? ❌
  2. Is there a file called `/notes/what-is-nginx.html`? βœ… Found it!
  
Nginx: "Here you go!" πŸ“–

Why Nginx and not just Caddy?

Caddy is great at being a doorman (routing, redirects, SSL). But Nginx is lightning fast at serving static files. The split is:

CaddyNginx
Routes visitors to the right placeServes the actual files
Handles redirectsServes HTML, CSS, JS, images
Talks to the outside worldStays in the back, only talks to Caddy
1 job: welcome + redirect1 job: serve files fast

The try_files trick β€” Clean URLs

This is where the magic of clean URLs happens:

try_files $uri $uri.html $uri/ =404;

When you visit /notes/what-is-nginx, Nginx:

  1. Tries /notes/what-is-nginx β†’ not a file
  2. Tries /notes/what-is-nginx.html β†’ found it! βœ…
  3. (Would try /notes/what-is-nginx/ directory if #2 failed)
  4. (Would show β€œ404 Not Found” if all failed)

This is why you can type garden.christianjeremia.com/notes/what-is-nginx without the .html β€” Nginx figures it out for you.


β‘€ VPS β€” The House 🏠

What is it?

VPS stands for Virtual Private Server. It’s a computer in a data center that’s always on, always connected to the internet.

Analogy: Renting a Room

Your laptop                        VPS
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ You write β”‚                  β”‚ Always-on    β”‚
β”‚ notes hereβ”‚                  β”‚ computer in  β”‚
β”‚ (Obsidian)β”‚                  β”‚ Singapore    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚                              β”‚
     β”‚ Git push/pull                 β”‚ Serves files
     β–Ό                              β–Ό
GitHub ─────── sync ──────→ VPS

Your laptop is like a phone β€” you turn it on/off, carry it around. The VPS is like a house β€” it’s always there, always ready.

What’s inside our VPS?

VPS (Tencent Cloud, Singapore, 2GB RAM)
β”œβ”€β”€ πŸ“ /home/ubuntu/obsidian-vault/   β†’ Raw notes (markdown files)
β”œβ”€β”€ πŸ“ /home/ubuntu/quartz-site/      β†’ Quartz builder
β”œβ”€β”€ πŸ“ /home/ubuntu/quartz-site/public/ β†’ Built website (HTML files)
β”œβ”€β”€ πŸšͺ Caddy (port 80)                β†’ Doorman
β”œβ”€β”€ πŸ—οΈ Nginx (port 8080)             β†’ Librarian
β”œβ”€β”€ πŸ€– Hermes Agent (Jeri)            β†’ AI assistant
└── πŸ—„οΈ Git                            β†’ Sync with GitHub

How data flows from VPS to you

                  Internet
VPS ─────────────────────────────────────→ Your Browser
 β”‚                                            β”‚
 β”‚ Built HTML files                           β”‚ Shows the page
 β”‚ (inside /public/)                          β”‚ Renders CSS
 β”‚                                            β”‚ Runs JavaScript
 β”‚                                            β”‚ Displays images

The VPS doesn’t β€œsend” data actively β€” it waits for someone to ask. When your browser asks β€œgive me /notes/index”, the VPS says β€œhere you go!” and sends the file.


The Full Journey β€” From Start to Finish 🎬

Let’s trace every step when you visit https://garden.christianjeremia.com:

Step 0: You type "garden.christianjeremia.com" in your browser
         and press Enter.
         
Step 1: πŸ“– DNS Lookup
         Your browser: "Who is garden.christianjeremia.com?"
         Cloudflare: "It's at IP 43.133.130.60"

Step 2: πŸ”’ SSL Handshake
         Your browser: "Hello, I'd like a secure connection"
         Cloudflare: "Here's my certificate. We're safe now."
         (Your browser & Cloudflare create an encrypted tunnel)

Step 3: 🌩️ Cloudflare processing
         Cloudflare receives your HTTPS request.
         Cloudflare: "Hmm, this is for the garden. 
                      Let me forward it to the VPS."
         Cloudflare decrypts your request, then sends it
         as plain HTTP to your VPS on port 80.

Step 4: πŸšͺ Caddy (The Doorman)
         Caddy on port 80 receives: "GET /"
         Caddy: "Root request? Let me redirect you to /notes/index"
         Caddy sends back: "Go to /notes/index instead"
         (This redirect is RELATIVE β€” no port number!)

Step 5: πŸ”„ Browser follows redirect
         Your browser: "OK, I'll go to /notes/index instead"
         Same DNS β†’ Same SSL β†’ Same Cloudflare β†’ Same Caddy

Step 6: πŸšͺ Caddy (Again)
         Caddy on port 80 receives: "GET /notes/index"
         Caddy: "Not a root request. I'll pass this to Nginx."
         Caddy forwards to localhost:8080

Step 7: πŸ—οΈ Nginx (The Librarian)
         Nginx on port 8080 receives: "GET /notes/index"
         Nginx: "Let me find that file..."
                  1. /notes/index β†’ not a file
                  2. /notes/index.html β†’ FOUND! βœ…
         Nginx reads the file and sends it back.

Step 8: πŸ“€ Response goes back
         Nginx β†’ Caddy β†’ Cloudflare β†’ Your Browser

Step 9: πŸŽ‰ Your browser renders the page
         The HTML tells your browser:
         - "Load these CSS files" β†’ makes it pretty
         - "Load this JavaScript" β†’ makes it interactive
         - "Show this text" β†’ the actual content
         - "Load these images" β†’ pictures and icons

Step 10: You see:
         🧠 Second Brain β€” Digital Garden
         "Welcome to the digital garden..."
         
         ✨ Done in about 0.3-1 second!

Summary Table

LayerNameJobAnalogy
β‘ DNS (Cloudflare)Translates domain β†’ IPPhone book πŸ“–
β‘‘SSL (Cloudflare)Encrypts your connectionSecurity guard πŸ”’
β‘’Reverse Proxy (Caddy)Routes visitors, handles redirectsDoorman πŸšͺ
β‘£Web Server (Nginx)Finds and serves filesLibrarian πŸ—οΈ
β‘€VPS (Tencent)The actual computer that runs everythingThe house 🏠

Why So Many Layers?

Good question! Why not just use one program for everything?

One giant programMultiple small programs
Does everything, but nothing greatEach does one job perfectly
If it breaks, EVERYTHING breaksIf one breaks, others still work
Hard to upgradeCan upgrade individually
In our case: hard to get clean URLsCaddy cleans URLs, Nginx serves fast

It’s like having separate tools in a toolbox:

  • A hammer for nails πŸ”¨
  • A screwdriver for screws πŸͺ›
  • A saw for wood πŸͺš

You could hammer a screw, but it’s better to use the right tool for each job.



πŸ“ Back to Notes

Made with πŸ§’ explanations β€” questions? Ask Jeri!