Installation
OpenSCM is designed to be lightweight with minimal dependencies, running on everything from enterprise servers to edge devices.
Prerequisites
| Requirement | Details |
|---|---|
| Operating System | Linux, Windows 10+, FreeBSD, macOS, Arch Linux |
| Architecture | x86_64, ARM64, ARMv7, i686, RISC-V 64, PowerPC 64 LE, s390x, LoongArch64 |
| Privileges | sudo (Linux/macOS) or Administrator (Windows) |
Server Installation
The server only needs to be installed once on a central host.
1. Set up the repository:
curl -sS https://repo.openscm.io/openscm.gpg | sudo gpg --dearmor -o /usr/share/keyrings/openscm.gpg
echo "deb [signed-by=/usr/share/keyrings/openscm.gpg] https://repo.openscm.io/stable/debian stable main" | sudo tee /etc/apt/sources.list.d/openscm.list
sudo apt update
2. Install:
1. Set up the repository:
sudo tee /etc/yum.repos.d/openscm.repo <<EOF
[openscm]
name=OpenSCM Stable
baseurl=https://repo.openscm.io/stable/redhat/
enabled=1
gpgcheck=1
gpgkey=https://repo.openscm.io/openscm.gpg
EOF
2. Install:
1. Set up the repository:
2. Install:
docker run -d \
--name openscm \
-p 8000:8000 \
-v openscm_config:/etc/openscm \
-v openscm_data:/var/lib/openscm \
openscm/scmserver:latest
Or using Docker Compose:
version: '3.8'
services:
openscm:
image: openscm/scmserver:latest
container_name: openscm
restart: unless-stopped
ports:
- "8000:8000"
volumes:
- openscm_data:/var/lib/openscm
- openscm_config:/etc/openscm
volumes:
openscm_data:
openscm_config:
Volume Backup
Always mount the /etc/openscm volume. If it is lost all registered
agents will need to re-register.
Download the installer from the Downloads page and run the setup wizard. The server will be registered as a Windows Service automatically.
Access the dashboard at http://localhost:8000 after installation.
Prefer a direct download? Get the latest packages from the Downloads page.
Agent Installation
Install the agent on every system you want to monitor. It is a single static binary with no runtime dependencies.
Linux, macOS and FreeBSD — one command
The script detects your distribution and CPU, installs the right package using
your own package manager, writes the agent config, and starts the service. On
Debian and RHEL-family systems it adds the OpenSCM package repository, so
apt upgrade / dnf upgrade keeps the agent current afterwards.
Add --dry-run to see exactly what it would do without changing anything, and
--help for the full list of options.
| Option | Description | Default |
|---|---|---|
--server URL |
Your OpenSCM server URL | required |
--organization ID |
Organization / tenant identifier | default |
--channel NAME |
stable or testing |
stable |
--version X.Y.Z |
Pin a specific version | newest published |
--heartbeat SECS |
Check-in interval | 300 |
--token TOKEN |
Enrollment token — auto-approves this system | — |
--dry-run |
Print every action, change nothing | — |
--uninstall |
Remove the agent | — |
--purge |
With --uninstall: also remove config, logs and the repository |
— |
Rolling out to many machines
Pass --token with an enrollment token and the
system is approved automatically instead of waiting in Systems as
pending. Mint tokens in the UI under Enrollment.
The token is a credential: prefer the OPENSCM_ENROLLMENT_TOKEN
environment variable over the command line, which is visible in ps and
recorded in shell history.
SaaS users
Pass --organization with your organization identifier. Without it the
agent enrolls into default, which is not your organization. The command
shown in the first-run tour already has your value filled in.
Supported: Debian, Ubuntu, RHEL, Fedora, CentOS, Rocky, Alma, openSUSE, Arch, FreeBSD and macOS — on every architecture the repository publishes. The script picks the correct one for the machine it runs on.
Removing the agent
Stops the service and removes the package, leaving the config and the OpenSCM
package repository in place. Add --purge to remove those too.
What --purge will not touch
/etc/openscm is shared with the server: it holds scmserver.config and
keys/scmserver.key. --purge removes only the agent's own files, and if
scmserver is installed it also leaves the package repository and log
directory alone rather than cutting the server off from updates.
The system stays listed in Systems until you delete it there; it simply stops checking in.
Windows
Download the installer from the Downloads page and run the setup wizard. The agent is registered as a Windows Service automatically, and the wizard prompts for the server URL.
Installing manually
The one-line installer is a convenience, not a requirement — it does exactly what the steps below do. Use these if you need to inspect each step, are building your own automation, or are working offline.
curl -sS https://repo.openscm.io/openscm.gpg -o /tmp/openscm.gpg
sudo pacman-key --add /tmp/openscm.gpg
sudo pacman-key --lsign-key 8A39E120F8B52DBB
sudo pacman -U https://repo.openscm.io/stable/arch/scmclient-0.8.0-1-x86_64.pkg.tar.zst
Published for x86_64, aarch64, armhf, ppc64le and riscv64. For
i686, s390x and LoongArch64 use the Debian or RPM packages.
Every architecture is listed on the Downloads page if you need a specific file. After a manual install, follow Post-Installation Setup below — the one-line installer does those steps for you.
Post-Installation Setup
Using the one-line installer?
Steps 1 and 2 are done for you — the agent is already configured and running. Go straight to 3. Approve the Agent, which is always required.
1. Configure the Agent
Edit the config file and point it to your server:
[server]
url = "https://your-openscm-server.com" # Your server URL
organization = "default" # Organization identifier
[client]
heartbeat = "300" # Check-in interval in seconds
loglevel = "info"
2. Restart the Agent
3. Approve the Agent
Once the agent starts it will send a registration request to the server.
- Log in to the OpenSCM dashboard
- Navigate to Systems
- Find the pending system and click Approve
The agent is now active and will begin receiving compliance tests.
First-run Setup
On a fresh installation, the dashboard will walk you through creating your admin account on the first visit. No default credentials are set.
Verify Installation
Health Probes
The server exposes two public, unauthenticated HTTP endpoints for use by load balancers, container orchestrators, and uptime monitors. Both are whitelisted by the init-guard middleware so they answer even before the first-run setup is complete — which means a Kubernetes pod can come up cleanly during a fresh install or a rolling upgrade with mid-flight migrations.
GET /health — liveness
"Is the process alive and accepting HTTP?" Returns immediately, no database query, no work.
$ curl -i http://localhost:8000/health
HTTP/1.1 200 OK
content-type: application/json
{"status":"ok"}
Use for Kubernetes livenessProbe, the Docker image's HEALTHCHECK, and
basic load-balancer pool-membership decisions. If /health ever stops
returning 200, the orchestrator should restart the container.
GET /ready — readiness
"Is the server able to serve real user traffic?" Returns 200 OK only
when the database pool answers a trivial query and the schema is set
up. Returns 503 Service Unavailable otherwise.
| Response | When | What it means |
|---|---|---|
200 OK with {"status":"ok","schema_version":N} |
DB reachable, schema present | Send traffic |
503 with {"status":"db_unavailable"} |
DB pool can't SELECT 1 |
Hold traffic; check disk / DB lock |
503 with {"status":"setup_pending"} |
Fresh install — /install not completed yet |
Hold traffic until the first-run wizard is finished |
Use for Kubernetes readinessProbe so the load balancer keeps the old
pod in rotation while a rolling deploy runs migrations on the new one.
Example wiring
Let the server compress — don't strip Accept-Encoding
Since 0.8.0 OpenSCM compresses its own responses (gzip/brotli) and
serves static assets with ETag + Cache-Control, which is most of the
reason a page costs ~290 KB instead of ~4.8 MB. Both depend on headers
surviving your reverse proxy:
- Forward the client's
Accept-Encodingheader. Some proxy configurations clear it, which silently disables compression. - Don't strip
ETagorCache-Controlfrom responses, or every navigation re-downloads the full asset set. - You do not need
gzip onin Nginx for OpenSCM's own responses — it will not double-compress something already carryingContent-Encoding. Leaving it on is harmless.
Both endpoints bypass the init-guard
Unlike every other route on the server, /health and /ready answer
even before /install has been completed. This is deliberate so that
a Kubernetes pod can be marked alive (and the load balancer can wait
for it to become ready) during the brief window between container
start and the first-run admin completing the setup wizard.