A self-hosted start page for your homelab.
1.5K
A self-hosted start page for your homelab. It shows the weather and your server's vitals at the top, and your links below, each with a live online/offline indicator.
HEAD request to every link (5 second timeout, cached
for 30 seconds). Any response below 500 counts as online. Self-signed certificates are accepted.Cmd+K / Ctrl+K opens a palette to jump to any link or search the web.The page refreshes its stats every 5 seconds.
services:
bercail:
image: orochibraru/bercail:latest
restart: unless-stopped
environment:
ORIGIN: 'https://dash.example.com'
ports:
- '3000:3000'
volumes:
- ./data:/app/data
Data lives in a SQLite file under /app/data. Database migrations run automatically on startup.
Everything is optional. For local development, copy .env.example to .env.
| Variable | Default | Description |
|---|---|---|
ORIGIN | none | Public URL of the app. Set it in production, forms fail without it behind a reverse proxy. |
PORT | 3000 | Port the server listens on. |
HOST | 0.0.0.0 | Address the server binds to. |
DB_FILE_NAME | data/db.sqlite | Path to the SQLite database. |
PUID / PGID | 10001 | Docker only. The uid/gid the server runs as. The data volume is chowned to match on startup. |
DISK_STATS_PATH | /System/Volumes/Data on macOS, / elsewhere | Filesystem the disk gauge reports on. |
WEATHER_LAT | none | Latitude for the weather. A location picked in Settings takes precedence. |
WEATHER_LON | none | Longitude for the weather. Must be set together with WEATHER_LAT. |
WEATHER_LOCATION_NAME | Home | Label shown for the location set through the variables above. |
WEATHER_UNITS | celsius | celsius or fahrenheit. |
OIDC_ISSUER | none | Issuer URL of your OpenID Connect provider. Setting it turns sign-in on. |
OIDC_CLIENT_ID | none | Client ID. Required with OIDC_ISSUER. |
OIDC_CLIENT_SECRET | none | Client secret. Required with OIDC_ISSUER. |
OIDC_ALLOWED_EMAILS | none | Comma-separated emails allowed to sign in. Unset lets in anyone the provider signs in. |
The first of these that is set wins:
WEATHER_LAT and WEATHER_LON.Without OIDC_ISSUER the app is open to anyone who can reach it. With it, every page asks for a
sign-in through your provider (Pocket ID, Authentik, Authelia, Keycloak, ...). Register a
confidential client with the redirect URL <ORIGIN>/auth/callback. Sessions last 30 days and
renew while in use.
Set OIDC_ALLOWED_EMAILS unless the provider already restricts who can use this client. With a
provider anyone can sign up to, leaving it unset lets anyone in.
/sys/class/thermal on Linux. On macOS it needs
osx-cpu-temp (brew install osx-cpu-temp).nvidia-smi on the host.A metric that can't be read shows N/A without affecting the others.
The extension in extension/ shows your Bercail instance on every new tab.
bercail-extension.zip from the latest release and unzip it. To build it yourself,
run bun run package:extension, which writes dist/bercail-extension.zip.chrome://extensions, turn on Developer mode, then Load unpacked and pick
the unzipped folder.If you put Bercail behind an auth proxy (Pangolin, Cloudflare Access) instead of using its own
sign-in, let /service-worker.js through without auth. Browsers fetch that file without cookies,
so otherwise the cache never installs.
After the first visit the page is served from a service worker cache, so new tabs open without waiting on the server.
Requires Bun and prek (brew install prek).
bun install # also installs the git hooks
bun dev
| Command | What it does |
|---|---|
bun run check | Type check |
bun run lint | Lint with Biome |
bun run lint:fix | Lint and apply fixes |
bun run format | Format TypeScript, Svelte and Markdown |
bun run test | Run the test suite |
prek run -a | Run every git hook against the whole repository |
The hooks format, lint, type check and test on commit, scan for secrets and typos, and require Conventional Commits messages.
SvelteKit 3 (prerelease) on Bun with remote functions, SQLite with Drizzle ORM, Tailwind CSS and shadcn-svelte components.
Every merge to main goes through semantic-release. A
feat, fix, perf, refactor or docs commit cuts a patch release: it updates
CHANGELOG.md, tags vX.Y.Z, creates the GitHub release with bercail-extension.zip attached,
and publishes the image under that tag and latest. Pull requests publish a pr-<number> image,
and their titles must be Conventional Commits because the squash merge uses them as the commit
message.
Content type
Image
Digest
sha256:aaf4db918…
Size
103.6 MB
Last updated
about 10 hours ago
docker pull orochibraru/bercail