intelidomWebsite/ADMIN_SETUP.md

120 lines
3.6 KiB
Markdown

# 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 <http://localhost:5173/admin>, 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.