External Scheduler Deployment
External Scheduler Deployment
The uptrakit-scheduler binary runs the scheduler as a standalone service, separate from the
controller. It enrolls as a service via WebSocket, receives infrastructure credentials automatically,
and executes the 4 external scheduled tasks (version checks, cleanup) using direct database access
and NATS messaging.
Internal tasks (CRL renewal, CA rotation check, service certificate check) run exclusively on the controller's embedded scheduler because they require in-process access to controller resources.
When to use the external scheduler
| Deployment | Scheduler | Notes |
|---|---|---|
| Single controller, simple | Embedded (--features embedded-scheduler) | Everything runs in one process |
| Single controller + NATS | External binary | Decoupled scheduling, independent scaling |
| Multi-controller HA | External binary | Avoids duplicate scheduling across controllers |
| Resilient single instance | Embedded + external | Embedded defers external tasks when external connects; resumes on disconnect |
Prerequisites
- A running Uptrakit controller with NATS configured (
--nats-url). - Network connectivity from the scheduler to the controller (WebSocket) and to the NATS server.
- Network connectivity from the scheduler to the database.
- The controller's master encryption key must be configured (the scheduler receives it via
ServiceCredentialsand uses it to unwrap data encryption keys from the database).
Installation
The uptrakit-scheduler binary is built from the crates/core/scheduler/ crate:
cargo build -p uptrakit-scheduler --release
Database backend features mirror the controller:
# SQLite (default)
cargo build -p uptrakit-scheduler --release
# PostgreSQL
cargo build -p uptrakit-scheduler --release --features db-postgres
# All backends
cargo build -p uptrakit-scheduler --release --features db-all
Enrollment
The scheduler enrolls like any other Uptrakit service (agent, MQTT bridge, SSH agent):
uptrakit-scheduler --url wss://controller.example.com:8443
On first run:
- The scheduler connects to the controller via WebSocket.
- It sends an
Enrollmessage with capabilities:scheduler,database_access,nats_access,master_key_access,graceful_shutdown. - An administrator approves the service (or provides an enrollment token for auto-approval).
- The scheduler requests and receives a client certificate.
- On the next connection (mTLS), the controller sends
ServiceCredentialscontaining the database URL, NATS URL, and master encryption key.
To auto-approve during enrollment:
uptrakit-scheduler --url wss://controller.example.com:8443 --enrollment-token <token>
CLI options
| Flag | Default | Description |
|---|---|---|
--url | (required) | Controller WebSocket URL |
--poll-interval-secs | 15 | How often the scheduler polls for due tasks (seconds) |
--tofu | — | Trust-on-first-use CA pinning |
--ca-cert | — | Path to controller's CA certificate |
--pki-addr | — | PKI endpoint for CA certificate |
--config-dir | Platform default | Override config directory |
--state-dir | Platform default | Override state directory |
--friendly-name | Hostname | Human-readable service name |
--enrollment-token | — | Auto-approval token |
--force-enroll | — | Force fresh enrollment |
-v, --verbose | 0 | Verbosity (up to -vvv) |
--version | — | Print build info and exit |
Credential flow
The scheduler advertises credential capabilities during enrollment. The controller automatically
sends ServiceCredentials on each authenticated connection:
| Capability | Credential | Description |
|---|---|---|
database_access | db_url | Database connection string |
nats_access | nats_url | NATS server URL |
master_key_access | master_key_hex | 256-bit master encryption key (hex) |
The scheduler capability is a marker — it does not grant credentials but identifies the service
type. When the controller detects a connected service with this capability, it defers external
tasks from the embedded scheduler.
Security considerations
The external scheduler receives sensitive infrastructure credentials:
- Database URL: Grants full read/write access to the application database.
- Master encryption key: Can unwrap DEKs and decrypt all encrypted fields in the database.
- NATS URL: Can publish messages to the NATS event stream.
When approving the scheduler service in the admin UI, security warnings are displayed for each credential capability. Approve only trusted scheduler instances.
The ServiceCredentials message is never published to NATS — it is delivered exclusively via
the authenticated WebSocket connection. See
Secrets and Encryption for the credential filtering
rationale.
Monitoring
- The scheduler's WebSocket connection to the controller serves as presence detection.
- When the
embedded-schedulerfeature is enabled on the controller, the embedded scheduler defers external tasks when an external scheduler connects and resumes them when it disconnects. Internal tasks (CRL renewal, CA rotation check, service cert check) always run on the embedded scheduler regardless of external scheduler presence. - The scheduler appears in the services list with the "Scheduler" label and can be managed via the REST API and admin UI.
- Logs use the
uptrakit_schedulertracing target. Use-vfor debug,-vvfor all uptrakit debug,-vvvfor trace.
Graceful shutdown
On SIGTERM or SIGINT, the scheduler:
- Cancels the scheduler engine loop.
- Releases all database claims (so another instance can pick up the tasks).
- Sends a
Disconnectingmessage to the controller. - Closes the WebSocket connection.
On SIGHUP, the scheduler exits with a restart outcome (suitable for systemd Restart=on-failure).
Systemd service example
[Unit]
Description=Uptrakit Scheduler
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/uptrakit-scheduler --url wss://controller.example.com:8443
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Related documentation
- Scheduler Architecture — database schema and HA claim mechanism
- Scheduler Engine (Development) — engine crate internals
- NATS Deployment — NATS JetStream configuration
- Secrets and Encryption — credential security model
- Service Lifecycle —
ServiceHandlertrait