Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,24 @@ WORLDMONITOR_VALID_KEYS=
# Convex deployment URL for email registration storage.
# Set up at: https://dashboard.convex.dev/
CONVEX_URL=


# ------ Discord Notifications (scripts/discord-notify.mjs) ------

# Discord Webhook URL — create via: Channel Settings → Integrations → Webhooks
# Required for periodic Discord notifications.
DISCORD_WEBHOOK_URL=

# Google Gemini API key — used to summarize world events for Discord posts.
# Free tier available at: https://aistudio.google.com/apikey
# If unset, OPENROUTER_API_KEY is used as fallback (google/gemini-2.5-flash).
GEMINI_API_KEY=

# Gemini model name (optional — defaults to gemini-2.0-flash)
GEMINI_MODEL=gemini-2.0-flash

# Notification interval in minutes (optional — defaults to 60)
DISCORD_NOTIFY_INTERVAL_MINUTES=60

# Summary language: ja (Japanese) or en (English) — defaults to ja
DISCORD_NOTIFY_LANGUAGE=ja
7 changes: 5 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
FROM node:22-alpine AS builder

WORKDIR /app
ENV NODE_OPTIONS=--max-old-space-size=4096

# Install root dependencies (layer-cached until package.json changes)
COPY package.json package-lock.json ./
Expand Down Expand Up @@ -40,6 +41,8 @@ WORKDIR /app
# API server
COPY --from=builder /app/src-tauri/sidecar/local-api-server.mjs ./local-api-server.mjs
COPY --from=builder /app/src-tauri/sidecar/package.json ./package.json
COPY --from=builder /app/scripts/discord-notify.mjs ./scripts/discord-notify.mjs
COPY --from=builder /app/scripts/_seed-utils.mjs ./scripts/_seed-utils.mjs

# API handler modules (JS originals + compiled TS bundles)
COPY --from=builder /app/api ./api
Expand All @@ -65,8 +68,8 @@ USER appuser

EXPOSE 8080

# Healthcheck via nginx
# Healthcheck checks container readiness, not seed freshness.
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
CMD wget -qO- http://localhost:8080/api/health || exit 1
CMD wget -q --spider http://127.0.0.1:8080/ || exit 1

CMD ["/app/entrypoint.sh"]
4 changes: 3 additions & 1 deletion Dockerfile.relay
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
FROM node:22-alpine

# curl required by OREF polling (Node.js JA3 fingerprint blocked by Akamai; curl passes)
RUN apk add --no-cache curl
# python3/make/g++ are required when ws native addons (bufferutil, utf-8-validate)
# do not have a matching prebuilt binary for the target architecture.
RUN apk add --no-cache curl python3 make g++

WORKDIR /app

Expand Down
22 changes: 22 additions & 0 deletions SELF_HOSTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ To automate, add a cron job:
*/30 * * * * cd /path/to/worldmonitor && ./scripts/run-seeders.sh >> /tmp/wm-seeders.log 2>&1
```

For 24/7 VPS operation, keep this cron job for seeders, but do not also schedule `scripts/discord-notify.mjs` from the host if the container is already running it under `supervisord`.

### 🔧 Manual seeder invocation

If you prefer to run seeders individually:
Expand Down Expand Up @@ -204,3 +206,23 @@ services:
| 🚢 No vessel data | Set `AISSTREAM_API_KEY` in both `worldmonitor` and `ais-relay` services |
| 🔥 No wildfire data | Set `NASA_FIRMS_API_KEY` |
| 🌐 No outage data | Requires `CLOUDFLARE_API_TOKEN` (paid Radar access) |

## 🖥️ Hetzner VPS Operations

For Hetzner Cloud, treat the VNC console as an emergency path only. Day-to-day management should happen over SSH with `systemd` and `docker compose`.

```bash
ssh root@your-server
systemctl status worldmonitor
journalctl -u worldmonitor -f
docker compose ps
docker compose logs -f worldmonitor
systemctl reload worldmonitor
```

Recommended baseline for 24/7 uptime:

- Enable Hetzner Backups or take a Snapshot before deployments.
- Mirror allowed ports in Hetzner Cloud Firewalls; do not rely on UFW alone for Docker-published ports.
- Use `/api/health` plus the bundled `scripts/health-check.sh` for alerting.
- Keep Discord notifications on a single execution path to avoid duplicate posts.
Loading