docker-compose.yml now pulls the pre-built image from gitea.labsconnect.se/bobban/scheduletaskmanager-schedule-task-manager:latest instead of building locally; the old build-from-source file moves to docker-compose.dev.yml for local testing or before a push pipeline exists. README documents both paths.
135 lines
5.2 KiB
Markdown
135 lines
5.2 KiB
Markdown
# Schedule Task Manager
|
|
|
|
Tracks scheduled tasks (cron jobs, systemd timers) across your homelab servers,
|
|
grouped by server and schedule type. Servers push their task list to this app
|
|
via a small agent script; sign-in is delegated to Authentik (OIDC).
|
|
|
|
v1 scope: Linux servers only (cron + systemd timers). Windows Task Scheduler
|
|
support is a documented future addition — see [`agent/windows/README.md`](agent/windows/README.md).
|
|
|
|
## Architecture
|
|
|
|
- `server/` — Express + TypeScript API, SQLite (via libSQL) storage, Authentik OIDC login.
|
|
- `web/` — React + Vite single-page app, served as static files by the Express server.
|
|
- `agent/linux/` — `report-tasks.sh` (collects cron + systemd timer data),
|
|
`install.sh` (installs it as a systemd timer on a target server), and
|
|
`uninstall.sh` (removes it).
|
|
|
|
Data model, API contract, and sync behavior are documented in code:
|
|
[`server/src/db/schema.ts`](server/src/db/schema.ts),
|
|
[`server/src/routes/agentReport.ts`](server/src/routes/agentReport.ts),
|
|
[`server/src/services/taskSync.ts`](server/src/services/taskSync.ts).
|
|
|
|
## 1. Set up an Authentik application
|
|
|
|
In Authentik:
|
|
|
|
1. Create an **OAuth2/OpenID Provider**:
|
|
- Redirect URI: `<APP_BASE_URL>/auth/callback` (e.g. `https://schedule.example.lan/auth/callback`)
|
|
- Scopes: `openid`, `email`, `profile`
|
|
2. Create an **Application** using that provider, and assign the users/groups who
|
|
should be allowed to sign in — Authentik controls who can authenticate; the
|
|
app itself has no separate user list.
|
|
3. Copy the provider's issuer URL, client ID, and client secret into `.env`
|
|
(see `.env.example`).
|
|
|
|
## 2. Run with Docker (recommended)
|
|
|
|
```sh
|
|
cp .env.example .env
|
|
# edit .env: APP_BASE_URL, SESSION_SECRET, AUTHENTIK_*
|
|
```
|
|
|
|
Two compose files, depending on where the image comes from:
|
|
|
|
- **`docker-compose.yml`** (production) — pulls
|
|
`gitea.labsconnect.se/bobban/scheduletaskmanager-schedule-task-manager:latest`.
|
|
Requires that image to already exist at that tag (pushed manually or by a
|
|
CI pipeline) and, if the registry is private, `docker login gitea.labsconnect.se`
|
|
first.
|
|
|
|
```sh
|
|
docker compose pull
|
|
docker compose up -d
|
|
```
|
|
|
|
- **`docker-compose.dev.yml`** — builds the image locally from source instead
|
|
of pulling. Use this for local testing or before a build pipeline exists.
|
|
|
|
```sh
|
|
docker compose -f docker-compose.dev.yml up -d --build
|
|
```
|
|
|
|
Either way, the app listens on `HOST_PORT` (default `3000`), and SQLite data
|
|
and session files persist in `./data` on the host.
|
|
|
|
## 3. Local development
|
|
|
|
Requires Node.js 20+.
|
|
|
|
```sh
|
|
npm install
|
|
cp .env.example .env # fill in AUTHENTIK_* to test real login, or leave
|
|
# blank to run everything except /auth/login locally
|
|
|
|
npm run dev:server # http://localhost:3000 (API)
|
|
npm run dev:web # http://localhost:5173 (Vite dev server, proxies /api and /auth to :3000)
|
|
```
|
|
|
|
Visit `http://localhost:5173` during development. Database migrations run
|
|
automatically on server start.
|
|
|
|
## 4. Add a server and install the agent
|
|
|
|
1. Sign in, go to **Servers**, and add a server. The generated API token is
|
|
shown once — copy it.
|
|
2. On the target Linux server, as root. If you're not already root, put
|
|
`sudo` right after the pipe so it elevates `bash`, not `curl` — `sudo curl
|
|
... | bash` would still fail the root check:
|
|
|
|
```sh
|
|
curl -fsSL https://schedule.example.lan/agent/linux/install.sh | \
|
|
sudo API_URL=https://schedule.example.lan API_TOKEN=stm_xxx bash
|
|
```
|
|
|
|
This installs `report-tasks.sh` to `/usr/local/bin`, writes the API
|
|
credentials to `/etc/schedule-task-manager-agent.env`, and installs a
|
|
`schedule-task-manager-agent.timer` systemd timer that reports every 15
|
|
minutes (override with `INTERVAL_MINUTES=5` before the `bash` above).
|
|
|
|
Requires `curl`, `jq`, and `systemd` on the target server — if either
|
|
`curl` or `jq` is missing, both this script and `report-tasks.sh` print
|
|
the right install command for the server's package manager (apt, dnf,
|
|
yum, apk, pacman, or zypper) and exit.
|
|
|
|
3. Tasks appear on the Dashboard, grouped by server and then by schedule type,
|
|
within one reporting interval.
|
|
|
|
Tasks that stop appearing in a server's report are marked **stale** rather
|
|
than deleted (so a temporary agent failure doesn't wipe history) and are
|
|
hidden by default — toggle "Show stale/missing tasks" to see them.
|
|
|
|
To remove the agent from a server, run:
|
|
|
|
```sh
|
|
curl -fsSL https://schedule.example.lan/agent/linux/uninstall.sh | sudo bash
|
|
```
|
|
|
|
This stops and deletes the systemd timer/service, the installed script, and
|
|
`/etc/schedule-task-manager-agent.env` (which holds the API token). It does
|
|
not delete the server's entry or task history in the app — the same "Uninstall"
|
|
button on the Servers page shows this command, and "Delete" removes the entry
|
|
entirely if you no longer want it tracked.
|
|
|
|
## 5. Manually tracked tasks
|
|
|
|
Not everything is discoverable by the agent — e.g. a scheduled job running
|
|
inside a Docker container. Use **Add task** on the Dashboard to log those by
|
|
hand. Manually entered tasks are never touched by agent reports (they have
|
|
their own `origin`), so they won't be marked stale or overwritten by the next
|
|
sync.
|
|
|
|
## Environment variables
|
|
|
|
See [`.env.example`](.env.example) for the full list with descriptions.
|