A self-hosted web dashboard for managing, running, and monitoring Python scripts. Features include loop scheduling, real-time log streaming, output download, role-based access control, and user management — all in a clean UI.
- Prerequisites
- Quick Start — Local PC
- Running on a Server (Docker)
- Configuration
- User Management
- Password Recovery
- Rotating the Master Password
- Stopping the App
- Troubleshooting
| Tool | Minimum version | Download |
|---|---|---|
| Python | 3.10 | https://python.org/downloads |
| Node.js | 18 | https://nodejs.org |
| Git | any | https://git-scm.com |
Windows note: the launcher expects the Python executable to be named
python. The official installer adds this automatically — make sure you tick "Add Python to PATH" during installation.
| Tool | Download |
|---|---|
| Docker Engine | https://docs.docker.com/engine/install |
| Docker Compose v2 | included with Docker Desktop; on Linux install the docker-compose-plugin |
These scripts set up a Python virtual environment, install all dependencies, and start both the backend (FastAPI) and frontend (Next.js) automatically. Data is stored in a ./data/ folder inside the repo — nothing is written outside the project directory.
git clone https://github.com/berrysekk/script-dashboard.git
cd script-dashboard
chmod +x dev.sh
./dev.shgit clone https://github.com/berrysekk/script-dashboard.git
cd script-dashboard
.\dev.ps1First time on Windows? PowerShell may block local scripts by default. Run this once in an admin PowerShell window, then retry:
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
Both services print their URLs once everything is ready:
┌─────────────────────────────────────────────┐
│ Frontend → http://localhost:3000 │
│ API → http://localhost:8000 │
│ Ctrl+C to stop both │
└─────────────────────────────────────────────┘
Open http://localhost:3000 in your browser.
On the very first start the app generates an admin account and a master password, then prints them to the console once:
[info] Bootstrap: admin account created — username: admin password: <generated>
[info] Bootstrap: master password written to data/master_password.hash — value: <generated>
Copy both values somewhere safe before closing the terminal. If you miss them, see Password Recovery.
You can also set credentials before first start using environment variables — see Configuration.
The dev.sh / dev.ps1 scripts are idempotent. Re-running them skips venv creation and dependency installation, so startup is fast after the first run.
The project ships with a docker-compose.yml ready for self-hosted servers and Unraid.
git clone https://github.com/berrysekk/script-dashboard.git
cd script-dashboardOpen docker-compose.yml and set your preferred credentials (optional — the app generates them if omitted):
environment:
ADMIN_USERNAME: admin
ADMIN_PASSWORD: change-me
MASTER_PASSWORD: pick-something-long-and-randomCredentials are consumed only on first start (when no database exists). Changing them in the compose file after the first start has no effect — use the UI or CLI instead.
If you forgot to note the generated passwords, pull them from the container logs:
docker exec script-dashboard sh -c 'grep -i -E "password|admin|master" /var/log/fastapi.stdout.log /var/log/fastapi.stderr.log'docker compose up -dThe dashboard is now available at http://<server-ip>:7080.
| Host path | Container path | Purpose |
|---|---|---|
/mnt/user/appdata/script-dashboard |
/data |
SQLite database, scripts, and logs |
Change the host path in docker-compose.yml to wherever you want data stored:
volumes:
- /your/chosen/path:/dataIf you want the dashboard to have its own IP address instead of a port on the host, uncomment the macvlan section at the bottom of docker-compose.yml and set a free IP on your LAN:
networks:
br0_macvlan:
ipv4_address: 192.168.1.100 # ← pick a free IPAll configuration is done through environment variables. For local dev, prefix the dev.sh command or set them in your shell before running the script. For Docker, add them under environment: in docker-compose.yml.
| Variable | Default | Purpose |
|---|---|---|
DATA_DIR |
/data (Docker) / ./data (local) |
Directory for the database, scripts, and logs |
ADMIN_USERNAME |
admin |
Username of the first admin account |
ADMIN_PASSWORD |
auto-generated | Password for the first admin. Generated and printed once on first start if not set |
MASTER_PASSWORD |
auto-generated | Shared recovery secret used by the "Forgot password?" flow. Generated and printed once on first start if not set |
Example — local dev with custom credentials:
ADMIN_USERNAME=jan ADMIN_PASSWORD=hunter2 ./dev.shExample — Docker with a custom data path:
services:
dashboard:
image: ghcr.io/berrysekk/script-dashboard:latest
ports:
- "7080:80"
volumes:
- /opt/script-dashboard:/data
environment:
ADMIN_USERNAME: jan
ADMIN_PASSWORD: hunter2
MASTER_PASSWORD: very-long-random-string
restart: unless-stoppedAdmins can manage users at /users in the web UI:
- Create, edit, and delete users
- Assign roles (
adminoruser) - Control which scripts each role can see and run
If you forget your password, use the Forgot password? link on the login page:
- Enter your username
- Enter the master password (the one generated on first start, or set via
MASTER_PASSWORD) - Enter and confirm a new password
The master password is a root-equivalent shared secret — store it offline.
The master password cannot be changed through the web UI by design — a compromised dashboard session can't replace your recovery secret.
To rotate it, open a shell and run:
Docker:
docker exec -it script-dashboard python -m backend.cli set-master-passwordLocal:
backend/.venv/bin/python -m backend.cli set-master-passwordThe CLI prompts for the new password twice and rewrites the hash file immediately.
If all admins are locked out and the master password is lost, you can reset a specific user directly:
Docker:
docker exec -it script-dashboard python -m backend.cli reset-password adminLocal:
backend/.venv/bin/python -m backend.cli reset-password adminLocal:
Press Ctrl+C in the terminal running dev.sh or dev.ps1. Both the backend and frontend stop cleanly.
Docker:
docker compose downAdd -v to also remove the data volume (destructive — deletes the database, scripts, and logs):
docker compose down -vPort 3000 or 8000 already in use
Something else is occupying the port. Find and stop it:
# Mac / Linux
lsof -i :8000
lsof -i :3000
# Windows (PowerShell)
netstat -ano | findstr :8000
netstat -ano | findstr :3000python3: command not found (Mac/Linux)
Install Python via your package manager or from https://python.org. On macOS with Homebrew:
brew install pythonpython: command not found (Windows)
Re-run the Python installer from https://python.org and ensure "Add Python to PATH" is checked. Then restart your PowerShell window.
PowerShell says "running scripts is disabled"
Run this once in an admin PowerShell, then retry .\dev.ps1:
Set-ExecutionPolicy -Scope CurrentUser RemoteSignedFrontend loads but API calls fail (spinning / errors in the UI)
The Next.js dev server proxies all /api/* requests to http://127.0.0.1:8000. If those fail, the backend isn't running. Check for errors in the terminal or in /tmp/sd-backend.log (Mac/Linux), then restart the dev script.
Container exits immediately on first start
Check the logs:
docker compose logs dashboardThe most common cause is a volume path that doesn't exist or isn't writable. Ensure the host path in volumes: is a directory Docker can write to.