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)
| Feature | What it does |
|---|---|
| DNS | garden A record → VPS IP (proxied/orange cloud) |
| SSL/TLS | Set to Flexible — Cloudflare handles HTTPS to visitors, sends plain HTTP to the VPS |
| CDN | Caches 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 Caddy | With Caddy |
|---|---|
Nginx on port 8080 leaks :8080 in redirects | Caddy 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/path | Redirects 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 301generates a relative redirect — no hostname, no portreverse_proxy localhost:8080forwards 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:
| Step | What 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
| Before | After |
|---|---|
http://<vps-ip>:8080 | https://garden.christianjeremia.com |
| No SSL (HTTP) | SSL via Cloudflare (HTTPS) |
| Port visible in redirects | Clean URLs |
| Hard to share | Easy to share |
| No CDN | Cloudflare CDN caching |
Why Caddy Instead of Just Nginx?
Good question! Could we make nginx listen on port 80 directly? Let’s compare:
| Approach | Pros | Cons |
|---|---|---|
| Caddy + Nginx (current) | Clean redirects, Caddy auto-managed, easy config | Extra moving part |
| Nginx on port 80 | One less service | Nginx adds port to redirects by default; would need workarounds like port_in_redirect off or explicit redirect URLs |
We use Caddy because:
- Its
redirdirective produces clean relative redirects natively - Caddy has a simpler config syntax than nginx
- It’s already on the system and handles port 80 nicely
- Nginx continues to do what it does best — serve static files fast
Related
- Quartz Digital Garden Setup — How the garden was built and deployed
- What is Nginx — Nginx basics and why we use it
- How Hermes Agent Works — The Engine Behind Jeri — The AI behind the setup