Documento setup dev e deploy in produzione self-hosted
Passo-passo per avviare lo stack Supabase in locale e per il deploy in produzione (dominio unico con routing /api/*, migrazioni, build/avvio Node, job pianificati), coerente con i file infra aggiunti nel commit precedente.
This commit is contained in:
@@ -30,7 +30,7 @@ rebase/amend/squash di commit già pushati).
|
||||
ancora da implementare
|
||||
- **Notifiche push**: convocazioni, promemoria allenamento/partita, turno palloni, esito finale
|
||||
|
||||
## Sviluppo
|
||||
## Sviluppo (locale)
|
||||
|
||||
Package manager: **bun** ([installazione](https://bun.sh)).
|
||||
|
||||
@@ -38,16 +38,67 @@ Package manager: **bun** ([installazione](https://bun.sh)).
|
||||
git clone https://github.com/ivancacciari1995-a11y/CRAPP.git
|
||||
cd CRAPP
|
||||
bun install
|
||||
bun run dev # avvia il dev server su http://localhost:8080
|
||||
```
|
||||
|
||||
Serve un file `.env` con le credenziali Supabase (`VITE_SUPABASE_URL`,
|
||||
`VITE_SUPABASE_PUBLISHABLE_KEY`) ed eventualmente le chiavi `VAPID_*` per le notifiche push.
|
||||
### 1. Avvia un backend Supabase
|
||||
|
||||
Serve un'istanza Supabase (cloud o self-hosted) a cui puntare. Per lavorare in locale senza
|
||||
toccare dati reali, nel repo c'è uno stack self-hosted pronto in `infra/supabase/docker/`:
|
||||
|
||||
```sh
|
||||
cd infra/supabase/docker
|
||||
cp .env.example .env
|
||||
sh utils/generate-keys.sh --update-env # genera JWT_SECRET, ANON_KEY, SERVICE_ROLE_KEY, ecc.
|
||||
```
|
||||
|
||||
Poi avvia lo stack (con `docker-compose.prod.yml` si tengono su solo i servizi che CrAPP usa
|
||||
davvero — vedi la sezione Produzione più sotto):
|
||||
|
||||
```sh
|
||||
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
||||
docker compose ps # verifica che tutti i container siano "healthy"
|
||||
```
|
||||
|
||||
Applica le migrazioni del progetto al database appena creato:
|
||||
|
||||
```sh
|
||||
cd ../../.. # torna alla root del repo
|
||||
for f in supabase/migrations/*.sql; do
|
||||
docker exec -i supabase-db psql -U postgres -d postgres -v ON_ERROR_STOP=1 < "$f"
|
||||
done
|
||||
```
|
||||
|
||||
### 2. Configura `.env` di CrAPP
|
||||
|
||||
Nella root del repo, crea `.env` con le chiavi lette da `infra/supabase/docker/.env`:
|
||||
|
||||
```
|
||||
VITE_SUPABASE_URL=http://localhost:8000
|
||||
VITE_SUPABASE_PUBLISHABLE_KEY=<ANON_KEY dello stack self-hosted>
|
||||
SUPABASE_SERVICE_ROLE_KEY=<SERVICE_ROLE_KEY dello stack self-hosted>
|
||||
```
|
||||
|
||||
Facoltative per testare le notifiche push (senza non si rompe nulla, semplicemente niente push):
|
||||
|
||||
```
|
||||
VAPID_PUBLIC_KEY=...
|
||||
VAPID_PRIVATE_KEY=...
|
||||
VAPID_SUBJECT=mailto:tuamail@esempio.it
|
||||
```
|
||||
|
||||
### 3. Avvia l'app
|
||||
|
||||
```sh
|
||||
bun run dev # http://localhost:8080
|
||||
```
|
||||
|
||||
Le tabelle sono vuote al primo avvio: crea un giocatore/evento dall'app stessa per avere dati di
|
||||
test. Dashboard Supabase Studio raggiungibile su `http://localhost:8000` (credenziali
|
||||
`DASHBOARD_USERNAME`/`DASHBOARD_PASSWORD` in `infra/supabase/docker/.env`).
|
||||
|
||||
Altri comandi:
|
||||
|
||||
```sh
|
||||
bun run build # build di produzione
|
||||
bun run build:dev # build in modalità development
|
||||
bun run preview # anteprima di una build
|
||||
bun run lint # eslint .
|
||||
@@ -56,6 +107,72 @@ bun run format # prettier --write .
|
||||
|
||||
Non è configurato un test runner.
|
||||
|
||||
## Produzione (self-hosted, Node + Docker)
|
||||
|
||||
`bun run build` usa Nitro (tramite `@lovable.dev/vite-tanstack-config`), che di default
|
||||
compilerebbe per Cloudflare Workers — in [vite.config.ts](vite.config.ts) il preset è forzato a
|
||||
`node-server` per generare un server Node standard, deployabile su qualunque host (coerente con
|
||||
[docs/PORTABILITA.md](docs/PORTABILITA.md)).
|
||||
|
||||
Passo passo, sul server di produzione:
|
||||
|
||||
0. **Dominio/DNS**: un solo hostname pubblico basta — `Caddyfile.example` instrada `/api/*`
|
||||
verso il gateway Supabase (path stripped) e tutto il resto verso l'app, sullo stesso dominio.
|
||||
- Con un dominio vero (DNS proprio): `tuodominio.it`.
|
||||
- Con un dominio **gratuito No-IP** (`ddns.net`, ecc.): un hostname singolo basta e avanza
|
||||
(il piano free ne dà fino a 3, ma qui ne serve uno solo), es. `crapp.ddns.net`.
|
||||
- Serve un client DDNS attivo sul server (o supporto nel router) che aggiorni l'IP: gli
|
||||
hostname No-IP gratuiti scadono dopo ~30 giorni di inattività se non confermati.
|
||||
- Verifica di non essere dietro **CGNAT** (IP pubblico condiviso dall'ISP): in quel caso
|
||||
nessuna porta è raggiungibile da internet e serve un tunnel (es. Cloudflare Tunnel) al
|
||||
posto dell'esposizione diretta.
|
||||
1. **Stack Supabase self-hosted**:
|
||||
```sh
|
||||
cp infra/supabase/docker/.env.production.example infra/supabase/docker/.env
|
||||
cd infra/supabase/docker
|
||||
sh utils/generate-keys.sh --update-env # secret NUOVI, non riusare quelli di sviluppo
|
||||
```
|
||||
Modifica nel `.env` appena creato: `SUPABASE_PUBLIC_URL`/`API_EXTERNAL_URL` (dominio del
|
||||
punto 0 + `/api`), `SITE_URL` (dominio del punto 0), `DASHBOARD_PASSWORD`, e l'SMTP se
|
||||
servono email vere. Poi avvia:
|
||||
```sh
|
||||
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
||||
```
|
||||
`docker-compose.prod.yml` fa due cose, pensate anche per girare su hardware limitato (es.
|
||||
Raspberry Pi 4): non espone porte pubblicamente (solo `127.0.0.1`, dietro il reverse proxy —
|
||||
vedi `Caddyfile.example` nella stessa cartella), e disattiva i servizi Supabase che CrAPP non
|
||||
usa (Realtime, Storage, imgproxy, Edge Functions, pooler) — restano solo `db`, `auth`, `rest`,
|
||||
`api-gw`, più `studio`+`meta` per guardare/gestire il database via interfaccia grafica
|
||||
(raggiungibile su `<dominio>/api`, con le credenziali `DASHBOARD_USERNAME`/
|
||||
`DASHBOARD_PASSWORD`). Da 11 container si scende a 6.
|
||||
2. **Migrazioni**:
|
||||
```sh
|
||||
cd ../.. # root del repo
|
||||
for f in supabase/migrations/*.sql; do
|
||||
docker exec -i supabase-db psql -U postgres -d postgres -v ON_ERROR_STOP=1 < "$f"
|
||||
done
|
||||
```
|
||||
3. **Reverse proxy TLS**: copia `infra/supabase/docker/Caddyfile.example` in `Caddyfile`,
|
||||
sostituisci il dominio del punto 0, poi `caddy run --config Caddyfile` (o come container).
|
||||
Gestisce automaticamente il certificato Let's Encrypt.
|
||||
4. **Env dell'app**:
|
||||
```sh
|
||||
cp .env.production.example .env
|
||||
```
|
||||
Compila `VITE_SUPABASE_URL` (dominio del punto 0 + `/api`),
|
||||
`VITE_SUPABASE_PUBLISHABLE_KEY` (= `ANON_KEY` dello stack), `SUPABASE_SERVICE_ROLE_KEY`
|
||||
(= `SERVICE_ROLE_KEY`), e le chiavi `VAPID_*` reali (`npx web-push generate-vapid-keys`).
|
||||
5. **Build e avvio**:
|
||||
```sh
|
||||
bun run build
|
||||
node .output/server/index.mjs # ascolta su PORT (default 3000)
|
||||
```
|
||||
Tienilo vivo con un process manager (pm2/systemd) — il Caddy del punto 3 lo espone via TLS
|
||||
sull'hostname app.
|
||||
6. **Job pianificati** — gli endpoint `src/routes/api/public/promemoria-palloni.ts` e
|
||||
`sollecita-presenze.ts` vanno richiamati periodicamente via HTTP POST da un cron di sistema o
|
||||
`pg_cron`: non partono da soli.
|
||||
|
||||
## Continuare da Lovable
|
||||
|
||||
Il progetto resta modificabile anche dall'[editor Lovable](https://lovable.dev/projects/8d07b0e4-6bd2-4a17-9dd2-bb2cf13f9f7c):
|
||||
|
||||
Reference in New Issue
Block a user