mirror of
https://github.com/Patiun/com.gregkilmer.www.git
synced 2026-11-08 04:08:24 +00:00
Initial Commit
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
# Deployment Guide
|
||||
|
||||
The site runs as a **Node server inside a container** on your homelab Cosmos
|
||||
system, fronted by your reverse proxy (Traefik / Caddy / nginx) with TLS for
|
||||
`patiun.com`.
|
||||
|
||||
---
|
||||
|
||||
## 1. Configure environment
|
||||
|
||||
Copy the example env file and fill in what you need:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
At minimum, set `SITE_URL` (your canonical public URL). To enable contact-form
|
||||
delivery, set **either** SMTP vars **or** `CONTACT_WEBHOOK_URL` (see
|
||||
[Contact delivery](#contact-delivery) below). Everything else is optional.
|
||||
|
||||
| Variable | Purpose | Default |
|
||||
|---|---|---|
|
||||
| `PORT` | Port the Node server binds to | `4321` |
|
||||
| `HOST` | Bind address (`0.0.0.0` for container) | `0.0.0.0` |
|
||||
| `SITE_URL` | Canonical URL for metadata | `https://patiun.com` |
|
||||
| `SMTP_HOST` / `SMTP_PORT` / `SMTP_USER` / `SMTP_PASS` | SMTP relay | unset |
|
||||
| `SMTP_FROM` | From address for outgoing mail | derived from `SITE_URL` |
|
||||
| `CONTACT_TO` | Inbox that receives submissions | `greg@patiun.com` |
|
||||
| `CONTACT_WEBHOOK_URL` | JSON webhook fallback (Discord/Slack/n8n) | unset |
|
||||
| `CONTACT_RATE_LIMIT` / `CONTACT_RATE_WINDOW_MIN` | Per-IP rate limit | `5` / `15` |
|
||||
|
||||
---
|
||||
|
||||
## 2. Build & run with Docker Compose
|
||||
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
This builds the multi-stage image (`Dockerfile`), starts the container, and maps
|
||||
host port `${HOST_PORT:-4321}` to container `4321`. Logs:
|
||||
|
||||
```bash
|
||||
docker compose logs -f greg-site
|
||||
```
|
||||
|
||||
Healthcheck hits `/` every 30s. Verify locally:
|
||||
|
||||
```bash
|
||||
curl http://localhost:4321/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Reverse proxy + TLS
|
||||
|
||||
Point your Cosmos reverse proxy at the container on port `4321`. The two common
|
||||
shapes:
|
||||
|
||||
### Option A — Traefik (labels)
|
||||
|
||||
If your Cosmos uses Traefik, add labels to the service in `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.greg-site.rule=Host(`patiun.com`)"
|
||||
- "traefik.http.routers.greg-site.entrypoints=websecure"
|
||||
- "traefik.http.routers.greg-site.tls.certresolver=your-resolver"
|
||||
- "traefik.http.services.greg-site.loadbalancer.server.port=4321"
|
||||
```
|
||||
|
||||
Then drop the `ports:` mapping and join the Traefik network instead.
|
||||
|
||||
### Option B — Caddy / nginx
|
||||
|
||||
Forward `patiun.com` (HTTPS) to `127.0.0.1:4321`. With Caddy, automatic TLS is a
|
||||
one-liner:
|
||||
|
||||
```caddyfile
|
||||
patiun.com {
|
||||
reverse_proxy 127.0.0.1:4321
|
||||
}
|
||||
```
|
||||
|
||||
Either way, ensure the proxy forwards `X-Forwarded-For` / `X-Real-IP` so the
|
||||
contact API's rate limiter sees real client IPs (not the proxy's).
|
||||
|
||||
---
|
||||
|
||||
## 4. Contact delivery
|
||||
|
||||
The `/api/contact` endpoint delivers submissions through the first configured
|
||||
path:
|
||||
|
||||
1. **SMTP** (if `SMTP_HOST` is set): sends a real email via nodemailer. Works
|
||||
with any SMTP relay (Gmail app-password, Mailgun, SES, your homelab mail
|
||||
server).
|
||||
2. **Webhook** (if `CONTACT_WEBHOOK_URL` is set and SMTP is not): POSTs a JSON
|
||||
payload `{ name, email, message, text }`. Great for a Discord/Slack/n8n
|
||||
inbound.
|
||||
3. **Neither configured**: returns `503` with a friendly "email me directly"
|
||||
message so the form never silently swallows input.
|
||||
|
||||
Test it:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:4321/api/contact \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"Test","email":"test@example.com","message":"Hello there."}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Updating the site
|
||||
|
||||
```bash
|
||||
git pull
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
The build stage reinstalls deps and rebuilds `dist/`; the runtime stage swaps in
|
||||
the new artifact with zero config.
|
||||
|
||||
---
|
||||
|
||||
## 6. Without Docker (bare Node)
|
||||
|
||||
If you prefer to run Node directly on the host:
|
||||
|
||||
```bash
|
||||
npm ci
|
||||
npm run build
|
||||
HOST=0.0.0.0 PORT=4321 SITE_URL=https://patiun.com node ./dist/server/entry.mjs
|
||||
```
|
||||
|
||||
Run it under a process manager (systemd, pm2) so it restarts on crash/boot.
|
||||
Reference in New Issue
Block a user