Garden Domain & HTTPS Setup

How garden.christianjeremia.com went from an IP-with-port to a clean, HTTPS-secured URL — and why there’s no port number showing anymore.

The Problem

The garden was accessible only at http://<vps-ip>:8080 — ugly, unencrypted, and hard to share. Every time someone visited the root, nginx would redirect to /notes/index but appended port 8080 to the URL:

http://<vps-ip>:8080
  ↓ (nginx redirect)
http://<vps-ip>:8080/notes/index   ← ":8080" in the URL

Not great for sharing with people.

The Solution — Three Layers

The setup uses three components working together:

Visitor → garden.christianjeremia.com
              ↓
        🌩️ Cloudflare (SSL + CDN + DDoS protection)
              ↓
        🚪 Caddy (port 80 — reverse proxy)
              ↓
        🏗️ Nginx (port 8080 — static file server)
              ↓
        📄 Quartz site (HTML, CSS, JS)

Layer 1: Cloudflare (The Shield)

FeatureWhat it does
DNSgarden A record → VPS IP (proxied/orange cloud)
SSL/TLSSet to Flexible — Cloudflare handles HTTPS to visitors, sends plain HTTP to the VPS
CDNCaches static assets at Cloudflare edge nodes worldwide

Why Flexible? The garden is a static site — no logins, no passwords, no user data. The traffic between Cloudflare’s Singapore edge and the VPS (both in Singapore data centers) travels over backbone links, not public internet. For a personal knowledge garden, this is more than sufficient.

💡 Later upgrade: Install a free Cloudflare Origin Certificate and switch to Full (Strict) for end-to-end encryption.

Layer 2: Caddy (The Door) — Why Caddy?

Caddy serves as the front door on port 80. Here’s why we added it:

Without CaddyWith Caddy
Nginx on port 8080 leaks :8080 in redirectsCaddy handles redirects cleanly — no port in URL
Nginx can’t bind to port 80 (blocked by cloud firewall?)Caddy handles port 80, proxies to nginx on 8080
Redirects include http://domain:8080/pathRedirects are relative (Location: /notes/index)

Caddyfile (/etc/caddy/Caddyfile):

http://garden.christianjeremia.com {
    # Redirect root → /notes/index (clean, no port!)
    redir / /notes/index 301
 
    # Proxy everything else to nginx
    reverse_proxy localhost:8080
}

Key points:

  • http:// prefix tells Caddy not to auto-redirect to HTTPS (Cloudflare already handles SSL)
  • redir / /notes/index 301 generates a relative redirect — no hostname, no port
  • reverse_proxy localhost:8080 forwards all other requests to nginx

Layer 3: Nginx (The Server)

Nginx listens on port 8080 and serves the actual Quartz static files. It’s no longer exposed to the internet directly — only Caddy talks to it.

Config (/etc/nginx/sites-enabled/obsidian-vault):

server {
    listen 8080;
    server_name _;
 
    root /home/ubuntu/quartz-site/public;
    index index.html;
 
    location / {
        try_files $uri $uri.html $uri/ =404;
    }
 
    # Cache static assets for 7 days
    location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|webp)$ {
        expires 7d;
        add_header Cache-Control "public, immutable";
    }
}

How a Request Flows

When you visit https://garden.christianjeremia.com:

StepWhat happens
1️⃣Browser asks Cloudflare for garden.christianjeremia.com
2️⃣Cloudflare terminates HTTPS, forwards HTTP to VPS port 80
3️⃣Caddy receives request for / → redirects to /notes/index (no port!)
4️⃣Browser follows redirect to https://garden.christianjeremia.com/notes/index
5️⃣Cloudflare → Caddy → Nginx (port 8080) serves the page

Result: Clean, beautiful URL — no :8080 anywhere

Comparison: Before vs After

BeforeAfter
http://<vps-ip>:8080https://garden.christianjeremia.com
No SSL (HTTP)SSL via Cloudflare (HTTPS)
Port visible in redirectsClean URLs
Hard to shareEasy to share
No CDNCloudflare CDN caching

Why Caddy Instead of Just Nginx?

Good question! Could we make nginx listen on port 80 directly? Let’s compare:

ApproachProsCons
Caddy + Nginx (current)Clean redirects, Caddy auto-managed, easy configExtra moving part
Nginx on port 80One less serviceNginx adds port to redirects by default; would need workarounds like port_in_redirect off or explicit redirect URLs

We use Caddy because:

  1. Its redir directive produces clean relative redirects natively
  2. Caddy has a simpler config syntax than nginx
  3. It’s already on the system and handles port 80 nicely
  4. Nginx continues to do what it does best — serve static files fast

📁 Back to Notes