feat(deploy): ambrosio production stack (erosi.oier.ovh)
Self-contained compose for a single-VPS deploy behind the host's Caddy. App + Supabase API share erosi.oier.ovh; Keycloak on auth.oier.ovh. - infra/docker-compose.erosi.yml — full stack bound to 127.0.0.1 only (db, auth, rest, realtime, storage, imgproxy, kong, meta, keycloak, app) - infra/caddy/erosi.Caddyfile — host-Caddy snippet with TLS + path routing (/auth /rest /storage /realtime /graphql → kong, rest → app) - infra/scripts/deploy-erosi.sh — rsync + first-run secret generation + build + migrations + Caddy snippet install - keycloak/realm-export.erosi.json — prod redirect URIs, registration on, client secret as __KEYCLOAK_CLIENT_SECRET__ placeholder (deploy sub'd) - .env.erosi.example — env template with placeholders Supporting fixes to make the deploy work on a clean Supabase-postgres volume: - infra/db-init/00-role-passwords.sh — rewrote as idempotent bootstrap: CREATE the Supabase service roles if missing, set passwords on pre-existing ones, enable pg_cron/pgcrypto/uuid-ossp, create auth/storage/graphql_public/ _realtime/realtime schemas, create empty supabase_realtime publication, set per-role search_path (auth→auth, storage→storage). Old version only ALTERed passwords and relied on the roles already existing — worked for a grandfathered dev volume, failed on a fresh prod init. - infra/db-init/00-role-passwords.sql — removed (folded into .sh). - apps/web/vite.config.ts — PWA strategy generateSW (was injectManifest). The plugin's injectManifest hardcodes the SW source filename to service-worker.js and ignores the filename: 'sw.ts' override, making the production build fail. generateSW's auto-generated precache-only SW is functionally equivalent to our 5-line src/sw.ts. Tested end-to-end on ambrosio: all 9 containers up, 11 migrations applied, https://erosi.oier.ovh returns 200, Keycloak OIDC discovery serves the correct issuer, /auth/v1/settings lists Keycloak as the sole external provider.
This commit is contained in:
@@ -11,14 +11,14 @@ export default defineConfig({
|
||||
}),
|
||||
sveltekit(),
|
||||
SvelteKitPWA({
|
||||
// Fase 6.1: custom SW at src/sw.ts (NOT src/service-worker.ts — SvelteKit
|
||||
// intercepts that filename and blocks Workbox imports; see gotcha #10
|
||||
// in CLAUDE.md). Minimal strategy: precache the built shell, no runtime
|
||||
// caching of Supabase. The $lib/sync pending_ops queue already handles
|
||||
// offline writes; SyncBanner surfaces offline state to the user.
|
||||
strategies: 'injectManifest',
|
||||
srcDir: 'src',
|
||||
filename: 'sw.ts',
|
||||
// `generateSW` strategy: the plugin auto-generates a Workbox SW that
|
||||
// precaches the built shell. Equivalent behavior to our previous
|
||||
// `src/sw.ts` (a 5-line precacheAndRoute wrapper) without the
|
||||
// injectManifest path, which in @vite-pwa/sveltekit 0.6.8 hardcodes
|
||||
// the SW source filename to `service-worker.js` and breaks on any
|
||||
// custom filename. The $lib/sync pending_ops queue handles offline
|
||||
// writes; SyncBanner surfaces offline state to the user.
|
||||
strategies: 'generateSW',
|
||||
scope: '/',
|
||||
base: '/',
|
||||
manifest: {
|
||||
@@ -37,8 +37,10 @@ export default defineConfig({
|
||||
{ src: '/icons/icon-512-maskable.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' }
|
||||
]
|
||||
},
|
||||
injectManifest: {
|
||||
globPatterns: ['client/**/*.{js,css,ico,png,svg,webp,woff,woff2}']
|
||||
workbox: {
|
||||
globPatterns: ['client/**/*.{js,css,ico,png,svg,webp,woff,woff2}'],
|
||||
// Supabase paths: never cache — always hit the network.
|
||||
navigateFallbackDenylist: [/^\/auth\//, /^\/rest\//, /^\/realtime\//, /^\/storage\//]
|
||||
},
|
||||
devOptions: {
|
||||
enabled: true,
|
||||
|
||||
Reference in New Issue
Block a user