Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Roster Scheduler

Build optimized 24/7 weekly rosters with configurable rules, availability, locks, and shift patterns.

CI React TypeScript Docker

Roster Scheduler is a self-hostable web application for creating a permanent one-week roster. It uses mixed-integer optimization to satisfy hard constraints and improve contract fulfillment, preferences, and fairness.

Features

  • Exact schedule optimization instead of greedy assignment
  • Configurable shift names, colors, and start/end times
  • Staff availability and preferred shifts
  • Preset and custom scheduling rules
  • Assignment locks preserved during regeneration
  • Deterministic generation and alternative optimized rosters
  • Rule violation and rest-period visualization
  • JSON, CSV, and print-ready PDF exports
  • Browser-local or Docker volume persistence
  • Light, dark, and system themes

Simple Docker Compose Quick Start

Create a file named compose.yaml:

services:
  roster-scheduler:
    image: ghcr.io/therealkraken/roster-scheduler:latest
    ports:
      - "3000:3000"
    environment:
      PERSISTENT_STORAGE: "true"
      DATA_DIR: /data
    volumes:
      - roster-data:/data
    restart: unless-stopped

volumes:
  roster-data:

Start the application:

docker compose up -d

Open http://localhost:3000.

Update later with:

docker compose pull
docker compose up -d

Quick Start: Docker Compose

Docker Compose enables shared persistent storage by default.

git clone https://github.com/TheRealKraken/roster-scheduler.git
cd roster-scheduler
docker compose up -d

Open http://localhost:3000.

Useful commands:

# View logs
docker compose logs -f

# Stop the application
docker compose down

# Update after pulling new code
git pull
docker compose pull
docker compose up -d

The named volume roster-scheduler_roster-data survives docker compose down. To also remove all persisted data, run docker compose down -v.

Published Container Images

GitHub Actions publishes multi-architecture images for linux/amd64 and linux/arm64:

  • Every push to main updates ghcr.io/therealkraken/roster-scheduler:latest
  • A tag such as v1.2.0 publishes v1.2.0, 1.2.0, and 1.2
  • Every build also receives an immutable commit SHA tag

Create a release image with:

git tag v1.0.0
git push origin v1.0.0

After the first workflow completes, open the roster-scheduler package on GitHub, select Package settings, and change its visibility to Public. Anonymous users can then run docker compose up -d without logging in to GHCR.

Quick Start: Docker Run

Run with persistent shared storage:

docker volume create roster-data

docker run -d \
  --name roster-scheduler \
  --restart unless-stopped \
  -p 3000:3000 \
  -e PERSISTENT_STORAGE=true \
  -e DATA_DIR=/data \
  -v roster-data:/data \
  ghcr.io/therealkraken/roster-scheduler:latest

Run with separate browser-local storage instead:

docker run -d \
  --name roster-scheduler \
  --restart unless-stopped \
  -p 3000:3000 \
  -e PERSISTENT_STORAGE=false \
  ghcr.io/therealkraken/roster-scheduler:latest

Storage Modes

Mode Setting Behavior
Browser PERSISTENT_STORAGE=false Every browser stores a separate roster in localStorage.
Server PERSISTENT_STORAGE=true Every browser shares one JSON roster stored in the mounted volume.

Persistent mode writes atomically to /data/roster-scheduler.json by default.

Environment variable Default Description
ROSTER_SCHEDULER_IMAGE ghcr.io/therealkraken/roster-scheduler:latest Image used by compose.yaml. Use a version tag to pin releases.
PERSISTENT_STORAGE false Enables the server-backed JSON store.
DATA_DIR /data Directory containing the persistent file.
DATA_FILE roster-scheduler.json File name within DATA_DIR.
PORT 3000 HTTP port inside the container.
HOST_PORT 3000 Host port used by compose.yaml.

To use a host directory instead of a named volume:

volumes:
  - /path/on/host:/data

To migrate browser data into persistent mode, export JSON in the application, enable persistent mode, then import the JSON file.

Local Development

Requirements: Node.js 22+ and npm.

npm install
npm run dev

Open http://localhost:5173.

Validation:

npm test
npm run lint
npm run build

Architecture

  • React and TypeScript frontend built with Vite
  • GLPK mixed-integer scheduling solver running in a browser worker
  • Express production server for static files and optional persistence
  • Atomic JSON writes for volume-backed deployments
  • No external database required

Backups

For browser mode, use the JSON export in the application.

For a named Docker volume:

docker run --rm \
  -v roster-scheduler_roster-data:/data \
  -v "$PWD":/backup \
  alpine tar czf /backup/roster-data-backup.tar.gz -C /data .

Security and Concurrency

Persistent mode provides one shared roster with last-write-wins behavior. It does not include authentication, authorization, audit history, or concurrent edit merging.

Do not expose the persistence API directly to the public internet without an authenticated reverse proxy or application-level authentication.

Licensing Note

The optimizer uses glpk.js, distributed under GPL-3.0. Review its obligations and choose a compatible repository license before distributing the application.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages