Public-cloud deployment of a single-user expense tracker: - 4-container stack: Caddy (HTTPS via Let's Encrypt), nginx (React/Vite SPA), Express API, Postgres 16 - Repeatable deployment via prepare-app.sh using only OCI CLI (no web console) - Persistent Postgres volume, auto-restart policies, healthchecks, backup + restore scripts - DuckDNS dynamic DNS for the public hostname; secrets isolated to gitignored .env Author: Gigi Saji Live URL: https://savesave.duckdns.org
64 lines
2.3 KiB
Markdown
64 lines
2.3 KiB
Markdown
# DuckDNS Setup (for HTTPS on sk1)
|
|
|
|
## What DuckDNS is
|
|
|
|
DuckDNS is a **free, donation-funded dynamic DNS service**. It gives you a subdomain under `duckdns.org` and an HTTP API to point it at any IP.
|
|
|
|
| Feature | Free? |
|
|
|---|---|
|
|
| 5 subdomains per account | ✅ |
|
|
| Unlimited updates via HTTP API | ✅ |
|
|
| IPv4 and IPv6 records | ✅ |
|
|
| Custom domains | ❌ (use a registrar instead) |
|
|
| Email / MX records | ❌ |
|
|
| Premium tier | does not exist |
|
|
|
|
No credit card. No expiration. Forever free.
|
|
|
|
## Why this project uses it
|
|
|
|
`prepare-app.sh` needs to point a DNS name at the new VM's public IP **before** Caddy starts, so Let's Encrypt's HTTP-01 challenge succeeds on the first try. DuckDNS is the simplest free option that has a scriptable update URL.
|
|
|
|
## One-time setup (90 seconds)
|
|
|
|
1. Go to **https://www.duckdns.org/**
|
|
2. Click **"sign in with GitHub"** (or Google / Twitter / Reddit)
|
|
3. In the **"domains"** box, type a name (e.g. `gigi-expenses`) and click **"add domain"**
|
|
→ your full hostname is now `gigi-expenses.duckdns.org`
|
|
4. At the top of the page, copy the **token** (a UUID like `abcd1234-…`)
|
|
|
|
## Put it in `sk1/.env`
|
|
|
|
```bash
|
|
DUCKDNS_DOMAIN=gigi-expenses.duckdns.org
|
|
DUCKDNS_TOKEN=abcd1234-aaaa-bbbb-cccc-1234567890ab
|
|
LE_EMAIL=you@example.com
|
|
```
|
|
|
|
That's it. `prepare-app.sh` will call the DuckDNS update API with these values during the deploy.
|
|
|
|
## Manual test (optional)
|
|
|
|
To verify the token works before running `prepare-app.sh`:
|
|
|
|
```bash
|
|
curl "https://www.duckdns.org/update?domains=gigi-expenses&token=YOUR_TOKEN&ip="
|
|
# should print: OK
|
|
```
|
|
|
|
(Leaving `ip=` empty makes DuckDNS auto-detect your current IP — useful for the sanity check; the real deploy passes the VM's IP explicitly.)
|
|
|
|
## Troubleshooting
|
|
|
|
| Response | Meaning | Fix |
|
|
|---|---|---|
|
|
| `OK` | Worked | — |
|
|
| `KO` | Wrong token or domain | Double-check both values; tokens are case-sensitive |
|
|
| timeout | Network/DNS issue on your side | Try again, or use a different DNS resolver |
|
|
|
|
## Limits worth knowing
|
|
|
|
- **DNS propagation:** usually < 30 seconds globally; sometimes up to a few minutes
|
|
- **Let's Encrypt rate limit:** 50 certs / week / registered domain; not a concern here since you'll only issue 1
|
|
- **DuckDNS API rate limit:** generous, not documented; nowhere near the few calls `prepare-app.sh` makes
|