docs: update AGENT.md + ARQUITECTURE.md — inline entrypoint, NPM full config, env vars, Unraid notes
This commit is contained in:
+74
-11
@@ -212,8 +212,6 @@ Host port mapping: `55521:8000` (8000 blocked by Docker Desktop's wslrelay on Wi
|
||||
|
||||
```
|
||||
frontend/
|
||||
├── Dockerfile (legacy, not used in Portainer deploy)
|
||||
├── 99-config.sh (entrypoint: writes config.js at boot)
|
||||
├── nginx.conf (serves /, gzip, cache headers)
|
||||
├── index.html app.js (public site, anon key, persistSession:false)
|
||||
├── admin.html admin.js (admin CRM, persistSession:true)
|
||||
@@ -223,8 +221,10 @@ frontend/
|
||||
└── datenschutz.html
|
||||
```
|
||||
|
||||
- `config.js` is generated at container start by `99-config.sh` (bind-mounted into `/docker-entrypoint.d/`) from `$SUPABASE_URL` and `$SUPABASE_ANON_KEY` only. The service_role key is never mounted into the web container.
|
||||
- The `web` service uses `nginx:1.27-alpine` directly with bind-mounted files (no `build:` step). This is Portainer-compatible: updating the frontend is `git pull` + container restart.
|
||||
- `config.js` is generated at container start by an **inline `entrypoint:` command** in `docker-compose.yml`. It writes `window.MCCARS_CONFIG={SUPABASE_URL,SUPABASE_ANON_KEY}` from the container's environment variables. No separate script file is used — Unraid's filesystem does not preserve Unix execute bits on bind mounts, so a mounted `.sh` file would be silently ignored.
|
||||
- `config.js` is **git-ignored**. The repo never ships a file with hardcoded URLs.
|
||||
- Both `index.html` and `admin.html` load `config.js` with `?v=<timestamp>` appended via an inline `document.write` snippet, ensuring proxies and browsers never cache a stale URL.
|
||||
- The `web` service uses `nginx:1.27-alpine` directly with bind-mounted files (no `build:` step). This is Portainer-compatible: updating the frontend is `git pull` + `docker compose up -d --force-recreate web`.
|
||||
- `admin.js` is ES modules, imports `@supabase/supabase-js` from `esm.sh` (CDN, pinned version). One Supabase client per page.
|
||||
- State lives in a single `state` object. Admin re-renders the active tab on realtime events.
|
||||
- Force-password-change modal is the only state that can preempt the rest of the admin UI after login.
|
||||
@@ -246,15 +246,78 @@ What's code/config (committed):
|
||||
|
||||
**Portainer deployment:**
|
||||
1. Clone repo to `/mnt/user/appdata/mc-cars`
|
||||
2. `chmod +x` the `.sh` files
|
||||
3. `mkdir -p data/{db,storage}`
|
||||
2. `mkdir -p data/{db,storage}`
|
||||
3. Edit `.env`: set `SITE_URL` and `SUPABASE_PUBLIC_URL` to your domain (see below)
|
||||
4. Portainer → Stacks → Add stack → paste compose + env vars → Deploy
|
||||
|
||||
**Nginx Proxy Manager (single public domain):**
|
||||
- Proxy `/` → `mccars-web:80` (or `<host>:55580`)
|
||||
- Custom locations `/auth/v1/`, `/rest/v1/`, `/realtime/v1/`, `/storage/v1/` → `mccars-kong:8000` (or `<host>:55521`)
|
||||
- Do **not** expose `/pg/` or Studio publicly
|
||||
- Update `.env` URLs to `https://cars.yourdomain.com`
|
||||
> No `chmod` needed. The entrypoint that writes `config.js` is an inline shell command in `docker-compose.yml`, not a bind-mounted script, so file permissions are irrelevant.
|
||||
|
||||
**Environment: two variables to change per environment**
|
||||
|
||||
| Variable | Local dev | Production (NAS) |
|
||||
|---|---|---|
|
||||
| `SITE_URL` | `http://localhost:55580` | `https://your.domain.com` |
|
||||
| `SUPABASE_PUBLIC_URL` | `http://localhost:55521` | `https://your.domain.com` |
|
||||
|
||||
All other GoTrue vars (`API_EXTERNAL_URL`, `GOTRUE_SITE_URL`, `GOTRUE_URI_ALLOW_LIST`) are derived from these two in `docker-compose.yml`.
|
||||
|
||||
**Nginx Proxy Manager (NPM) — required settings for single-domain HTTPS:**
|
||||
|
||||
Create one proxy host for your domain (e.g. `demo.lago.dev`):
|
||||
|
||||
*Details tab:*
|
||||
- Scheme: `http`
|
||||
- Forward Hostname / IP: `<NAS IP>` (e.g. `192.168.178.3`)
|
||||
- Forward Port: `55580`
|
||||
- Cache Assets: **OFF** (if left ON, NPM caches `config.js` and serves stale URLs)
|
||||
- Websockets Support: **ON** (required for Realtime)
|
||||
- Block Common Exploits: ON
|
||||
|
||||
*SSL tab:*
|
||||
- SSL Certificate: your domain cert
|
||||
- Force SSL: **ON**
|
||||
- HTTP/2 Support: **ON**
|
||||
|
||||
*Advanced tab (⚙️) — paste this exactly:*
|
||||
|
||||
```nginx
|
||||
location /auth/v1/ {
|
||||
proxy_pass http://192.168.178.3:55521;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /rest/v1/ {
|
||||
proxy_pass http://192.168.178.3:55521;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /realtime/v1/ {
|
||||
proxy_pass http://192.168.178.3:55521;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
location /storage/v1/ {
|
||||
proxy_pass http://192.168.178.3:55521;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
```
|
||||
|
||||
This routes `https://your.domain.com/` → nginx (static site) and all API paths → Kong. Do **not** expose `/pg/` or Studio publicly.
|
||||
|
||||
For real deployments:
|
||||
1. Generate a new `JWT_SECRET` and matching `ANON_KEY` / `SERVICE_ROLE_KEY` (see Supabase self-hosting docs).
|
||||
|
||||
Reference in New Issue
Block a user