Docker Deployment
A HarborGuard sensor runs as a single container and only needs three things: the platform URL, an API key, and access to a container runtime that can pull and inspect images.
Prerequisites
- Docker 20.10+ (or any OCI-compatible runtime exposing
/var/run/docker.sock). - Outbound HTTPS to your HarborGuard URL.
- An API key with the
developerrole minimum. Generate it in Settings -> API Keys. - Network reachability to the registry the sensor will scan (so the sensor can
docker pullfrom it).
Running the sensor
The minimal form is enough to register, start heartbeating, and pick up scan jobs for any registry whose scanning.method is set to sensor. The production-shaped form adds resource limits, a persistent scanner-DB cache, registry credentials, and a healthcheck.
What each production flag buys you:
| Flag | Why |
|---|---|
--restart unless-stopped | Sensor recovers across host reboots and crashes. |
--memory 2g --cpus 2 | Trivy + Grype + Syft running concurrently can spike RAM on large images. 2 GB is a safe floor. |
-v ...:/var/run/docker.sock | Required - the sensor pulls and inspects images via the host Docker daemon. |
-v harborguard-cache:/var/cache/harborguard | Persists scanner DBs (Trivy, Grype) across restarts. Saves 100-300 MB of cold-start downloads. |
| Healthcheck | Lets your orchestrator notice a wedged sensor process. |
Registry credentials
The sensor needs to pull the images it scans. Two ways to give it credentials:
1. Pass them as env vars (single registry)
The sensor logs in to that registry on startup.
2. Mount a Docker config (multiple registries)
The sensor uses whatever docker login has already cached. Best for hosts that scan images from several registries.
Required scopes
| Registry | Minimum scope |
|---|---|
| Docker Hub | read:public for public images, plus repo read for private. |
| GHCR | read:packages |
| ECR | ecr:GetAuthorizationToken, ecr:BatchGetImage, ecr:GetDownloadUrlForLayer |
| GCR / Artifact Registry | roles/artifactregistry.reader |
| ACR | AcrPull |
| Quay | Robot account with read on each repo |
| Harbor | Project guest+ with pull |
The sensor does not need push or admin scopes for vulnerability scanning. Patch operations (separate capability) require push to the destination registry.
docker-compose example
Verifying the sensor is up
After docker run, within ~30 seconds:
Check the Sensors panel
The Sensors panel in the UI shows the sensor as online with a recent heartbeat.
Inspect the logs
You should see registered, then heartbeat ok lines on a regular cadence. Job claims log as claimed scan-....
Trigger a test scan
Trigger a scan against a registry whose scanning.method is sensor. The scan should move from PENDING to IN_PROGRESS to COMPLETED without ever leaving your network.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| Sensor never registers | API key wrong, or HARBORGUARD_URL unreachable from the host. |
Status stays offline | Outbound HTTPS blocked. Sensor needs to reach HARBORGUARD_URL. |
Scans FAILED with pull errors | Sensor cannot pull from the registry. Check credentials or docker login. |
Scans FAILED with permission errors on the socket | The Docker socket path is owned by docker:docker. Either run the container as root or join the docker group. |
| Sensor keeps OOM-killing | Bump --memory. Large multi-GB images plus parallel engines can need 4-8 GB. |