3.6 KiB
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) andeditor(content only)
The
data/folder (database + uploads) is git-ignored — it lives only on the machine that runs the app.
Local development
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
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_LIMITmatters: without raising it, uploading a normal phone photo fails with 413 Payload Too Large.
3. Initialise the database + first admin
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):
[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:
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:
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.