scd-server Installation
scd-server is distributed as a self-contained binary — no Node.js required on the target machine. Alternatively, run it from source with Node.js 22.
Option A: Binary (recommended)
Download the binary for your platform from the GitHub releases page.
| Platform | File |
|---|---|
| macOS (Apple Silicon) | scd-server-macos-arm64 |
| macOS (Intel) | scd-server-macos-x64 |
| Linux (x64) | scd-server-linux-x64 |
| Windows (x64) | scd-server-win-x64.exe |
After downloading, code-sign the binary before running:
codesign --sign - ./scd-server-macos-arm64
Run scd-server.exe directly — do not run it via node scd-server.exe. The binary is a native executable, not a JavaScript file.
Option B: From source
Requires Node.js 22.5 or later (for node:sqlite built-in).
git clone https://github.com/activemindsolutions/scd-server.git
cd scd-server
npm install
First-time setup
Run the init command to create the required directory structure and a starter config:
# Binary
./scd-server --init
# From source
node server.js --init
This creates:
data/directoryconfig.ymlfrom the built-in template- Checks for
license.keyandscd-public.pem
Configuration
Open config.yml and set the required values:
# Server
port: 3000
host: 0.0.0.0
# API token — used by the scd CLI to authenticate
# Generate a random string of at least 32 characters
api_token: <your-api-token>
# Admin path — obfuscated path prefix for the admin UI
# Use a random string of at least 8 characters
admin_path: <your-admin-path>
# Optional: SMTP for email notifications
# smtp_host: mail.example.com
# smtp_port: 587
# smtp_user: notifications@example.com
# smtp_pass: <password>
# smtp_from: scd-server <notifications@example.com>
# Optional: Discord webhook for notifications
# discord_webhook: https://discord.com/api/webhooks/...
api_token and admin_path should be treated as secrets. Use a password manager to generate them. The admin path obscures the admin UI from scanners — it is not a substitute for the authentication, but adds a layer of defence.
Place your license file
Copy your license.key file into the data/ directory:
data/
license.key ← your signed license file
scd-public.pem ← included in the distribution
If no license.key is present, scd-server starts in development mode with full access. On a production install, a missing or invalid license degrades to restricted mode.
Start the server
# Binary
./scd-server
# From source
node server.js
# Custom port
./scd-server --port 8080
# With debug logging
./scd-server --debug
Verify it is running:
curl http://localhost:3000/api/v1/health
# { "status": "ok", ... }
Port conflict
If the port is already in use, scd-server prints a clear message and exits:
Port 3000 is already in use. Is scd-server already running?
Change port with: ./scd-server --port <port> or set port in config.yml
Running as a service
For production use, run scd-server as a system service so it starts automatically on reboot.
Linux (systemd)
Create /etc/systemd/system/scd-server.service:
[Unit]
Description=scd-server
After=network.target
[Service]
Type=simple
User=scd
WorkingDirectory=/opt/scd-server
ExecStart=/opt/scd-server/scd-server-linux-x64
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Enable and start:
systemctl enable scd-server
systemctl start scd-server
systemctl status scd-server
macOS (launchd)
Create ~/Library/LaunchAgents/se.activemind.scd-server.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>se.activemind.scd-server</string>
<key>ProgramArguments</key>
<array>
<string>/opt/scd-server/scd-server-macos-arm64</string>
</array>
<key>WorkingDirectory</key>
<string>/opt/scd-server</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
Load it:
launchctl load ~/Library/LaunchAgents/se.activemind.scd-server.plist