Skip to content

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 developer role minimum. Generate it in Settings -> API Keys.
  • Network reachability to the registry the sensor will scan (so the sensor can docker pull from 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.

docker run -d \
  --name harborguard-sensor \
  --restart unless-stopped \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e HARBORGUARD_URL=https://harborguard.co \
  -e HARBORGUARD_API_KEY=hg_live_xxxxxxxxxxxxxxxx \
  -e SENSOR_NAME=prod-vpc-east \
  ghcr.io/harborguard/sensor:latest

What each production flag buys you:

FlagWhy
--restart unless-stoppedSensor recovers across host reboots and crashes.
--memory 2g --cpus 2Trivy + Grype + Syft running concurrently can spike RAM on large images. 2 GB is a safe floor.
-v ...:/var/run/docker.sockRequired - the sensor pulls and inspects images via the host Docker daemon.
-v harborguard-cache:/var/cache/harborguardPersists scanner DBs (Trivy, Grype) across restarts. Saves 100-300 MB of cold-start downloads.
HealthcheckLets 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)

REGISTRY_URL=ghcr.io
REGISTRY_USERNAME=ci-bot
REGISTRY_PASSWORD=ghp_xxxx

The sensor logs in to that registry on startup.

2. Mount a Docker config (multiple registries)

-v $HOME/.docker/config.json:/root/.docker/config.json:ro

The sensor uses whatever docker login has already cached. Best for hosts that scan images from several registries.

Required scopes

RegistryMinimum scope
Docker Hubread:public for public images, plus repo read for private.
GHCRread:packages
ECRecr:GetAuthorizationToken, ecr:BatchGetImage, ecr:GetDownloadUrlForLayer
GCR / Artifact Registryroles/artifactregistry.reader
ACRAcrPull
QuayRobot account with read on each repo
HarborProject 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

services:
  harborguard-sensor:
    image: ghcr.io/harborguard/sensor:latest
    container_name: harborguard-sensor
    restart: unless-stopped
    mem_limit: 2g
    cpus: 2.0
    environment:
      HARBORGUARD_URL: https://harborguard.co
      HARBORGUARD_API_KEY: ${HARBORGUARD_API_KEY}
      SENSOR_NAME: prod-vpc-east
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - harborguard-cache:/var/cache/harborguard
      - ${HOME}/.docker/config.json:/root/.docker/config.json:ro
    healthcheck:
      test: ["CMD", "pgrep", "-f", "sensor"]
      interval: 30s
      timeout: 5s
      retries: 3
 
volumes:
  harborguard-cache:

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

docker logs -f harborguard-sensor

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

SymptomLikely cause
Sensor never registersAPI key wrong, or HARBORGUARD_URL unreachable from the host.
Status stays offlineOutbound HTTPS blocked. Sensor needs to reach HARBORGUARD_URL.
Scans FAILED with pull errorsSensor cannot pull from the registry. Check credentials or docker login.
Scans FAILED with permission errors on the socketThe Docker socket path is owned by docker:docker. Either run the container as root or join the docker group.
Sensor keeps OOM-killingBump --memory. Large multi-GB images plus parallel engines can need 4-8 GB.

On this page