Self-Hosted Deployment
Humifortis is designed to run entirely within your own infrastructure. No call-home, no license server, no cloud dependency.
What Gets Deployed
| Component | Description |
|---|---|
| humifortis | Go binary — risk engine + dashboard API + embedded frontend |
| Redis | Real-time state: risk scores, velocity tracking, pub/sub |
| PostgreSQL (optional) | Dashboard persistence: entities, alerts, API keys, audit trail |
| Keycloak (optional) | Your IdP with the Humifortis connector — via compose integration profile |
| Datadog Agent (optional) | APM + metrics + trace collection |
Redis is the only hard runtime dependency. PostgreSQL is required for the dashboard UI and audit trail.
Option 1 — Docker (Recommended)
The official image is published to GitHub Container Registry:
docker pull ghcr.io/humifortis/humifortis-core:latest
Minimal run (Redis must be available separately):
docker run -p 8080:8080 \
-e REDIS_URL=redis://your-redis-host:6379 \
-e JWT_SECRET=change-me-min-32-characters \
-e JITTER_SECRET=change-me-random-string \
ghcr.io/humifortis/humifortis-core:latest
Option 2 — Docker Compose (Full Stack)
1. Get the compose file and env template
# Download compose file and env template from the v1.0.0 release
curl -LO https://github.com/humifortis/humifortis-engine/releases/download/v1.0.0/default.env.example
cp default.env.example .env
# Edit .env with your values (see section below)
Then use the compose file distributed with the release (or pull directly from the repo).
2. Configure .env
Required:
PORT=8080
ENV=production
# Redis (required)
REDIS_URL=redis://redis:6379
# Database (required for dashboard)
DATABASE_URL=postgres://humifortis:yourpassword@postgres:5432/humifortis?sslmode=disable
POSTGRES_PASSWORD=yourpassword
# Security — generate unique values per deployment
JWT_SECRET=change-me-min-32-characters
JITTER_SECRET=change-me-random-string
# Risk state — 7-day sliding TTL (don't set below 24h)
RISK_STATE_TTL_HOURS=168
# Worker pool
WORKER_POOL_SIZE=10
WORKER_POOL_BUFFER=5000
Optional:
# GeoIP — MaxMind databases (Tor/VPN detection, impossible travel)
GEOIP_CITY_DB=data/GeoLite2-City.mmdb
GEOIP_ASN_DB=data/GeoLite2-ASN.mmdb
# Datadog APM
DD_API_KEY=your-datadog-key
DD_AGENT_HOST=localhost:8126
DD_ENV=production
DD_SERVICE=humifortis
# S3 audit sink
AUDIT_S3_BUCKET=my-audit-bucket
AUDIT_S3_REGION=us-east-1
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
# CORS (dashboard)
CORS_ALLOWED_ORIGINS=https://your-app.example.com
3. Start the stack
Core stack (risk engine + dashboard):
docker compose up -d
With Keycloak and MailPit (for integration testing):
docker compose --profile integration up -d
4. Verify
# Health check
curl http://localhost:8080/health
# Access points
# http://your-server:8080/ → Humifortis dashboard
# http://your-server:8088/ → Keycloak admin (profile: integration)
# http://your-server:8025/ → MailPit SMTP UI (profile: integration)
Option 3 — Binary (Bare-Metal / Air-Gapped)
Pre-built binaries are published with each release on GitHub:
# Linux amd64
curl -LO https://github.com/humifortis/humifortis-engine/releases/download/v1.0.0/humifortis-engine-v1.0.0-linux-amd64.tar.gz
# Verify checksum
curl -LO https://github.com/humifortis/humifortis-engine/releases/download/v1.0.0/SHA256SUMS
sha256sum -c SHA256SUMS 2>&1 | grep OK
# Extract and install
tar -xzf humifortis-engine-v1.0.0-linux-amd64.tar.gz
chmod +x humifortis-engine-v1.0.0-linux-amd64
mv humifortis-engine-v1.0.0-linux-amd64 /opt/humifortis/bin/humifortis
Available platforms:
| Platform | File |
|---|---|
| Linux amd64 | humifortis-engine-v1.0.0-linux-amd64.tar.gz |
| Linux arm64 | humifortis-engine-v1.0.0-linux-arm64.tar.gz |
| macOS amd64 | humifortis-engine-v1.0.0-darwin-amd64.tar.gz |
| macOS arm64 (M-series) | humifortis-engine-v1.0.0-darwin-arm64.tar.gz |
| Windows amd64 | humifortis-engine-v1.0.0-windows-amd64.zip |
Systemd service
# /etc/systemd/system/humifortis.service
[Unit]
Description=Humifortis Risk Engine
After=network-online.target postgresql.service redis.service
Wants=network-online.target
[Service]
Type=simple
User=humifortis
WorkingDirectory=/opt/humifortis
EnvironmentFile=/opt/humifortis/.env
ExecStart=/opt/humifortis/bin/humifortis
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
useradd --system --no-create-home humifortis
mkdir -p /opt/humifortis/bin
# place binary and .env here
systemctl daemon-reload
systemctl enable --now humifortis
Security Hardening
- Run as a dedicated non-root user
- Use TLS in front of the dashboard (Nginx + Let's Encrypt or internal CA)
- Generate unique
JWT_SECRETandJITTER_SECRETper deployment — never reuse across environments - Use a strong
POSTGRES_PASSWORD(16+ random characters) - Restrict PostgreSQL to localhost or your private network only
- For high-security environments: configure
HUMIFORTIS_FALLBACK_ALLOW=falseon the Keycloak connector so logins are blocked (not allowed) if the engine is unreachable
Upgrading
# Docker Compose
docker compose pull
docker compose up -d
# Binary (systemd)
systemctl stop humifortis
# download new binary (see Option 3)
mv new-binary /opt/humifortis/bin/humifortis
systemctl start humifortis
Database migrations run automatically on startup.
Air-Gapped Deployment
Export the image on a connected machine:
docker pull ghcr.io/humifortis/humifortis-core:latest
docker save ghcr.io/humifortis/humifortis-core:latest | gzip > humifortis.tar.gz
Transfer to the air-gapped host and load:
docker load < humifortis.tar.gz
docker run -p 8080:8080 --env-file .env ghcr.io/humifortis/humifortis-core:latest
Alternatively, use the pre-built binary — it has no network dependencies at runtime.
See Also
- Keycloak Connector — connect your Keycloak instance
- API Reference — query risk scores and submit events
- FAQ — common deployment questions