Skip to main content

Self-Hosted Deployment

On-premise is a first-class option

Humifortis is designed to run entirely within your own infrastructure. No call-home, no license server, no cloud dependency.


What Gets Deployed

ComponentDescription
humifortisGo binary — risk engine + dashboard API + embedded frontend
RedisReal-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.


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:

PlatformFile
Linux amd64humifortis-engine-v1.0.0-linux-amd64.tar.gz
Linux arm64humifortis-engine-v1.0.0-linux-arm64.tar.gz
macOS amd64humifortis-engine-v1.0.0-darwin-amd64.tar.gz
macOS arm64 (M-series)humifortis-engine-v1.0.0-darwin-arm64.tar.gz
Windows amd64humifortis-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_SECRET and JITTER_SECRET per 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=false on 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