Skip to content

About

Self-hosted, multi-user grade tracker and exam planner. Manage subjects, weighted averages, notes and attachments with private accounts, 2FA and PDF/ZIP exports. Runs with Docker and SQLite. English and German. No cloud services or telemetry.

Topics

Resources

Security policy

Stars

24 stars

Watchers

0 watching

Forks

Repository files navigation

GradeShelf - a self-hosted grade tracker and exam planner

Get started  ·  Features  ·  Update & back up  ·  Configure  ·  Website  ·  Releases

Private accounts  ·  Light & dark mode  ·  Desktop & mobile

GradeShelf dashboard showing grade averages, upcoming exams and personal grade lists

Your overview, from upcoming exams to the latest results. Screenshots use example data.

A closer look at a grade list

A grade list with subjects, weighted averages, recorded grades and upcoming exams

Features

Grades & averages

Use simple grades, fixed percentage shares or grouped assessments. Choose a grading scale per list, with optional school-year halves or four upper-secondary semesters.

Exam planning

Plan upcoming exams, add results later and see which grades are still missing.

Notes & files

Keep notes and attachments with each entry. Export your data as a ZIP or a readable PDF report.

Calendar subscription

Follow selected lists in Apple Calendar, Outlook or another ICS-compatible calendar.

Private accounts

Share an instance with separate accounts, admin-managed roles and optional two-factor authentication.

SSO login

Connect existing accounts to an OpenID Connect provider. Local sign-in remains available.

Normal grade lists keep their existing calculation. Upper-secondary lists track calculated averages and received final grades separately. Different scales are never combined. The optional target calculator shows what one additional grade would need to achieve. See the releases for release notes.

Installation

Requires Docker with Compose v2, curl and OpenSSL. Docker images are available for amd64 and arm64; no Node.js installation is needed on the host.

1. Install

Run the installer in a new directory:

mkdir -p gradeshelf
cd gradeshelf
curl -fSL --proto '=https' --proto-redir '=https' \
  https://raw.githubusercontent.com/14flavius/GradeShelf/main/scripts/install.sh \
  -o install.sh &&
sh install.sh

Follow the prompts for the instance name, browser URL, port and listen address. Use the exact URL you will open in your browser, including https:// behind a reverse proxy. The installer creates the configuration and starts GradeShelf. For an existing installation, follow Updates and backups.

2. Sign in

Open the URL you configured during installation.

Username Initial password
gradeshelf gradeshelf0000

Important

Change the initial password when prompted, before making the instance public.

Create accounts and manage roles in Admin. There is no public registration; administrators cannot view another user's grades or files. Personal settings, including two-factor authentication, are under Settings.

Updates and backups

Update

Customized installations with subject categories and course half-years must use the import procedure below before starting the new version.

For regular installations, back up and update from your installation directory:

sh scripts/backup.sh && docker compose pull && docker compose up -d --wait

Keep your existing .env and data/ directory. Regular installations keep their accounts, grades and attachments; database migrations run automatically on startup. If you pin an image version, update GRADESHELF_IMAGE first. New images are available once the release build finishes.

Back up

To create a backup without updating:

sh scripts/backup.sh

The backup briefly stops a running instance, saves its data and configuration to backups/, then starts it again. Keep a protected copy outside the server. The database and uploads live in ./data; preserve this directory when replacing containers.

Restore a backup

Stop the app and restore a backup marked COMPLETE into a separate recovery directory: copy .env, the full data/ directory and the saved Compose file. Restore docker-compose.yml.backup as docker-compose.yml.

Use the matching image version and ensure data/ is writable by UID/GID 1000. Verify the restored installation before replacing the original. Downgrading the Docker image alone does not undo database migrations.

Import a customized installation

The importer supports the customized v1.2.0 schema with subject categories, grade groups and four course half-years. Stop the old instance and back up its data and configuration. From a v1.3.0 development checkout, preview the import:

npm run import:legacy -- --source /path/to/source-data --target /path/to/new-data

Add --apply to import into a new, nonexistent directory. The source stays unchanged; accounts and attachments are retained. Use the standard Compose configuration with the imported directory mounted at /data and keep the existing BETTER_AUTH_SECRET. Remove old app-custom mounts that replace application files, then start v1.3.0. Review any unassigned periods or types; final grades are not inferred from averages. Invalid weights or relationships stop the import. The source database and uploads are required; SQL migration scripts alone do not contain your data.

Configuration

Edit .env in your installation directory, then apply changes:

docker compose up -d --pull never --wait
Setting Purpose
BETTER_AUTH_URL Full browser URL, such as https://grades.example.com. Subpaths are not supported.
PORT Published HTTP port on the host, usually 3000.
BIND_ADDRESS 127.0.0.1 for local access or a proxy on the same host; 0.0.0.0 for LAN access.
GRADESHELF_IMAGE Optional fixed image, e.g. ghcr.io/14flavius/gradeshelf:1.3.0. Defaults to latest.

Keep the generated BETTER_AUTH_SECRET and COMPOSE_PROJECT_NAME unchanged. For HTTPS, terminate TLS at your reverse proxy and forward to GradeShelf's HTTP port. A proxy in another container needs network access to the app; its localhost is separate from the host's.

Change the display name, legal notice and administrator contact in Admin → Instance settings. See .env.example and docker-compose.yml for all deployment options.

Connect SSO

  1. Register a confidential OIDC client with your provider using Authorization Code with PKCE (S256) and scopes openid profile email. Use client_secret_basic or client_secret_post and ensure an email address is supplied.
  2. In Admin → Advanced features → SSO login, enter the exact issuer URL, client ID and client secret. Register the displayed callback URL with your provider, check the configuration, then enable SSO and save.
  3. Sign in locally and connect your account under Settings → Security → SSO login. Use Confirm local sign-in if prompted. Future visits can use the SSO login button.

Use HTTPS and make sure the provider is reachable from both GradeShelf and your browser. SSO connects existing accounts; it does not create users or synchronize roles. Keep a local administrator login available and configure SSO two-factor authentication at the provider.

Saving SSO settings ends existing SSO sessions. If the issuer or client ID changes, users must reconnect their accounts. Signing out of GradeShelf does not sign out of the provider. To block access immediately, deactivate the account in GradeShelf; a provider-only suspension does not end existing GradeShelf sessions.

Upload limits

Add these optional settings to .env and ensure they are passed through in your docker-compose.yml:

Setting Default Allowed values
UPLOAD_MAX_FILE_MB 10 1–100 MiB per file
UPLOAD_MAX_FILES_PER_ENTRY 10 1–100 files per entry
UPLOAD_MAX_USER_GB 0 (unlimited) 0–1024 GiB of attachments per user; decimals allowed

Lowering a limit does not delete existing files.

Multiple instances

Use a separate directory, Compose project name and host port for each instance. Use separate hostnames for independent browser logins; cookies are shared across ports on the same hostname. Run one app instance per database on local disk.

Help

Questions or problems? Open an issue. For startup problems, check docker compose logs --tail=100 and docker compose ps. Remove secrets and personal information before sharing logs.

To create an additional administrator from the terminal:

docker compose exec gradeshelf npm run admin:create

Development

Run locally and check your changes

Use Node.js 24.11+ within the Node 24 release line. The app uses Next.js, TypeScript, Tailwind, Better Auth and Prisma.

git clone https://github.com/14flavius/GradeShelf.git gradeshelf
cd gradeshelf
sh scripts/setup.sh
npm ci
npm run db:generate
npm run db:init
npm run dev -- --hostname 127.0.0.1

Checks: npm run lint, npm run format:check, npm run typecheck, npm run db:validate, npm run build. On existing databases, apply migrations with npm run db:deploy; never reset them.


Install GradeShelf  ·  Get help  ·  Visit the website

By Flavius Hager  ·  MIT License
Most of the original GradeShelf foundation was vibe-coded with AI assistance.

About

Self-hosted, multi-user grade tracker and exam planner. Manage subjects, weighted averages, notes and attachments with private accounts, 2FA and PDF/ZIP exports. Runs with Docker and SQLite. English and German. No cloud services or telemetry.

Topics

Resources

Security policy

Stars

24 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages