# Admin dashboard & gallery — self-hosted setup The site is a **SvelteKit app running on Node** (`adapter-node`) with a local **SQLite** database and image files stored on disk. It's meant to run on your own server behind **nginx**. No third-party services. - Database: SQLite file at `DATABASE_PATH` (default `./data/app.db`) - Uploaded images: files under `UPLOADS_DIR` (default `./data/uploads`) - Auth: server-side sessions (httpOnly cookie), passwords hashed with argon2 - Roles: `admin` (manage users + content) and `editor` (content only) > The `data/` folder (database + uploads) is git-ignored — it lives only on the > machine that runs the app. ## Local development ```sh npm install npm run db:migrate # create ./data/app.db with the tables npm run create-admin -- --email you@example.com --password "yourpassword" --name "Ime" --role admin npm run dev ``` Then open , log in, and manage the gallery. The public gallery is at `/gallery` (also linked from the header). ## Production (your home server) ### 1. Build ```sh npm install npm run build # outputs the Node server to ./build ``` ### 2. Environment variables | Variable | Purpose | Example | |---|---|---| | `ORIGIN` | **Required.** Public URL, for correct cookies/CSRF behind nginx | `https://intelidom.si` | | `PORT` | Port the Node app listens on | `3000` | | `BODY_SIZE_LIMIT` | **Max upload size** — the default is only 512 KB, too small for photos | `52428800` (50 MB) | | `DATABASE_PATH` | SQLite file location | `/srv/intelidom/data/app.db` | | `UPLOADS_DIR` | Uploaded images directory | `/srv/intelidom/data/uploads` | > `BODY_SIZE_LIMIT` matters: without raising it, uploading a normal phone photo > fails with **413 Payload Too Large**. ### 3. Initialise the database + first admin ```sh npm run db:migrate # uses DATABASE_PATH npm run create-admin -- --email you@example.com --password "strongpassword" --role admin ``` (Migrations also run automatically on app startup, so this is mainly to seed the first admin before the app runs. Additional users can be added the same way, or via the dashboard once Phase 2 lands.) ### 4. Run it Example `systemd` service (`/etc/systemd/system/intelidom.service`): ```ini [Service] WorkingDirectory=/srv/intelidom ExecStart=/usr/bin/node build Environment=ORIGIN=https://intelidom.si Environment=PORT=3000 Environment=BODY_SIZE_LIMIT=52428800 Environment=DATABASE_PATH=/srv/intelidom/data/app.db Environment=UPLOADS_DIR=/srv/intelidom/data/uploads Restart=always User=www-data [Install] WantedBy=multi-user.target ``` `sudo systemctl enable --now intelidom` to start it. ### 5. nginx Reverse-proxy to the Node app and let nginx serve uploaded images directly: ```nginx server { server_name intelidom.si; # ... your TLS certs ... client_max_body_size 50m; # must be >= BODY_SIZE_LIMIT for uploads location /uploads/ { alias /srv/intelidom/data/uploads/; expires 30d; } location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` ### 6. Backups Everything worth backing up is in the data directory — back it up regularly: ```sh cp -r /srv/intelidom/data /backups/intelidom-$(date +%F) ``` ## Migrating the old Supabase gallery The previous version stored gallery images in Supabase. There's no automatic import — simply **re-upload** those images through the new `/admin` dashboard. Keep the old Supabase project until you've done so, then it can be deleted.