Add deployment architecture diagram and update README
Mermaid flowchart covers: GoDaddy DDNS, pfSense NAT + split DNS, Let's Encrypt DNS-01, nginx SSL termination, Docker host-network containers, Proton Bridge SMTP relay, and Gitea git workflow. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
140
README.md
140
README.md
@@ -1,72 +1,134 @@
|
||||
# www.kenjim.com
|
||||
|
||||
Static website served via nginx Docker container on zet.home.arpa, proxied through nginx SSL termination at `https://www.kenjim.com`.
|
||||
KenJim Technologies marketing site — React SPA with Express contact form backend, deployed on **zet.home.arpa** behind nginx SSL termination.
|
||||
|
||||
## Development Workflow
|
||||
## Deployment Architecture
|
||||
|
||||
Edit on Mac → push to Gitea → pull on zet → site updates live.
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph internet["Internet"]
|
||||
browser(["Client browser"])
|
||||
godaddy["GoDaddy DNS\nwww.kenjim.com CNAME → lair.kenjim.com\nlair.kenjim.com A → WAN IP (dynamic)"]
|
||||
le["Let's Encrypt CA"]
|
||||
end
|
||||
|
||||
```
|
||||
Mac Gitea (git.kenjim.com) zet.home.arpa
|
||||
│ git push │ │
|
||||
├─────────────────────────────────►│ │
|
||||
│ │ git pull │
|
||||
│ ├───────────────────────────►│
|
||||
│ │ │ docker compose up -d
|
||||
subgraph pfsense["pfSense · home gateway"]
|
||||
ddns["DDNS client\nupdates lair.kenjim.com A record\nwhen WAN IP changes"]
|
||||
nat["NAT / Port Forward\nWAN :80 / :443 → zet :80 / :443"]
|
||||
unbound["Unbound DNS Resolver\nwww / git / kenji.kenjim.com\n→ 172.27.0.35 (split DNS — bypasses NAT)"]
|
||||
end
|
||||
|
||||
subgraph zet["zet.home.arpa · 172.27.0.35"]
|
||||
subgraph ssl["SSL — acme.sh + Let's Encrypt"]
|
||||
acme["acme.sh\nDNS-01 challenge via GoDaddy API"]
|
||||
cert["/etc/nginx/ssl/kenjim.com/\nfullchain.pem · key.pem\nauto-renewed by cron"]
|
||||
end
|
||||
|
||||
subgraph nginx_host["nginx · host process"]
|
||||
nginxsrv[":80 → redirect HTTPS\n:443 · SSL termination\nproxy_pass → localhost:8080"]
|
||||
end
|
||||
|
||||
subgraph docker["Docker · network_mode: host"]
|
||||
fe["www-kenjim-frontend\nnginx :8080\nReact SPA (pre-built image)\n/api/* proxied → :3001"]
|
||||
api["www-kenjim-api\nExpress.js :3001\nPOST /contact handler"]
|
||||
end
|
||||
|
||||
bridge["Proton Mail Bridge\n127.0.0.1:1025 SMTP relay"]
|
||||
gitea[("Gitea · git.kenjim.com\nkenjim/www.kenjim.com")]
|
||||
end
|
||||
|
||||
protonmail["Proton Mail\ninfo@kenjim.com → kenji@kenjim.com"]
|
||||
|
||||
browser -->|"DNS lookup"| godaddy
|
||||
browser -->|"HTTPS :443"| nat
|
||||
nat -->|"port forward"| nginxsrv
|
||||
unbound -.->|"LAN clients resolve direct"| nginxsrv
|
||||
|
||||
nginxsrv -->|"proxy_pass :8080"| fe
|
||||
fe -->|"proxy /api/*"| api
|
||||
api -->|"SMTP 127.0.0.1:1025"| bridge
|
||||
bridge -->|"relay via Proton servers"| protonmail
|
||||
|
||||
acme <-->|"set DNS TXT record\nfor domain validation"| godaddy
|
||||
acme <-->|"certificate issuance"| le
|
||||
acme -->|"writes cert"| cert
|
||||
cert -->|"loaded by"| nginxsrv
|
||||
|
||||
ddns -->|"keeps A record current"| godaddy
|
||||
|
||||
gitea -->|"git pull · docker compose up --build"| fe
|
||||
gitea -->|"git pull · docker compose up --build"| api
|
||||
```
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
www.kenjim.com/
|
||||
├── docker-compose.yml # runs nginx:alpine on host port 8080
|
||||
└── html/ # web root — edit files here
|
||||
└── index.html
|
||||
├── docker-compose.yml # both services run network_mode: host
|
||||
├── frontend/
|
||||
│ ├── Dockerfile # node:20 build → nginx:alpine serve
|
||||
│ ├── nginx.conf # :8080, SPA fallback, /api/ proxy → :3001
|
||||
│ └── src/ # React source (Vite)
|
||||
└── backend/
|
||||
├── Dockerfile
|
||||
└── server.js # Express, POST /contact → nodemailer
|
||||
```
|
||||
|
||||
All files under `html/` are served directly. No build step required for static content.
|
||||
## Development Workflow
|
||||
|
||||
Edit on Mac → push to Gitea → pull + rebuild on zet:
|
||||
|
||||
```
|
||||
Mac Gitea (git.kenjim.com) zet.home.arpa
|
||||
│ git push │ │
|
||||
├──────────────────────────────►│ │
|
||||
│ │ git pull │
|
||||
│ ├─────────────────────────►│
|
||||
│ │ │ docker compose up --build -d
|
||||
```
|
||||
|
||||
## Running on zet
|
||||
|
||||
```bash
|
||||
cd ~/workspace/src/personal/www.kenjim.com
|
||||
|
||||
docker compose up -d # start
|
||||
docker compose down # stop
|
||||
docker compose logs -f # watch logs
|
||||
docker compose up --build -d # build images and start
|
||||
docker compose down # stop
|
||||
docker compose logs -f # watch logs
|
||||
docker logs www-kenjim-api # backend only
|
||||
docker logs www-kenjim-frontend # frontend only
|
||||
```
|
||||
|
||||
## Deploying Changes
|
||||
## Environment
|
||||
|
||||
On zet after pushing from Mac:
|
||||
`.env` lives on zet only (not in git). Required vars:
|
||||
|
||||
| Variable | Example | Notes |
|
||||
|---|---|---|
|
||||
| `SMTP_HOST` | `127.0.0.1` | Proton Bridge SMTP host |
|
||||
| `SMTP_PORT` | `1025` | Proton Bridge SMTP port |
|
||||
| `SMTP_SECURE` | `false` | Bridge uses STARTTLS, not SSL-on-connect |
|
||||
| `SMTP_USER` | `kenji@kenjim.com` | Bridge auth credential |
|
||||
| `SMTP_PASS` | `<bridge-password>` | From Bridge SMTP settings |
|
||||
| `FROM_EMAIL` | `info@kenjim.com` | Sender address shown in emails |
|
||||
| `CONTACT_TO` | `info@kenjim.com` | Destination for contact form submissions |
|
||||
|
||||
## SSL Certificate
|
||||
|
||||
Issued by Let's Encrypt via DNS-01 challenge using the GoDaddy API. Managed by acme.sh on zet:
|
||||
|
||||
```bash
|
||||
cd ~/workspace/src/personal/www.kenjim.com
|
||||
git pull
|
||||
# nginx:alpine picks up file changes immediately via volume mount — no restart needed
|
||||
# manual renewal (cron handles this automatically)
|
||||
~/.acme.sh/acme.sh --renew -d kenjim.com --wildcard --dns dns_gd
|
||||
```
|
||||
|
||||
If `docker-compose.yml` itself changes, recreate the container:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## How It Connects to nginx
|
||||
|
||||
The container listens on host port `8080`. The nginx reverse proxy on zet routes `https://www.kenjim.com` → `http://127.0.0.1:8080`.
|
||||
|
||||
See `~/workspace/src/personal/appa-net/zet.home.arpa/nginx/kenjim.conf` for the nginx config.
|
||||
Cert location: `/etc/nginx/ssl/kenjim.com/`
|
||||
|
||||
## Mac Setup (first time)
|
||||
|
||||
```bash
|
||||
# Clone the repo on your Mac
|
||||
git clone http://kenjim@git.kenjim.com/kenjim/www.kenjim.com.git
|
||||
cd www.kenjim.com
|
||||
|
||||
# Edit html/ files, then:
|
||||
git add .
|
||||
git commit -m "your message"
|
||||
git push
|
||||
# edit frontend/src, then:
|
||||
git add . && git commit -m "..." && git push
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user