On-Prem Installation & Upgrade Guide
Prerequisites
- Docker 24+ with Compose plugin
- 10GB free disk space minimum
- Ports: 80, 443 (production with HTTPS) or 3000, 3001 (development)
- OS: Linux (recommended), macOS (development)
Fresh Installation
Step 1: Download the On-Prem Bundle
Download the bundle for your platform from the latest release:
# macOS (Apple Silicon)
curl -LO https://github.com/KafkaGuard/kafkaguard-releases/releases/download/v2.3.0/kafkaguard-onprem-v2.3.0-Darwin_arm64.tar.gz
tar -xzf kafkaguard-onprem-v2.3.0-Darwin_arm64.tar.gz
cd kafkaguard-onprem-v2.3.0/
# macOS (Intel)
curl -LO https://github.com/KafkaGuard/kafkaguard-releases/releases/download/v2.3.0/kafkaguard-onprem-v2.3.0-Darwin_x86_64.tar.gz
tar -xzf kafkaguard-onprem-v2.3.0-Darwin_x86_64.tar.gz
cd kafkaguard-onprem-v2.3.0/
# Linux (x86_64)
curl -LO https://github.com/KafkaGuard/kafkaguard-releases/releases/download/v2.3.0/kafkaguard-onprem-v2.3.0-Linux_x86_64.tar.gz
tar -xzf kafkaguard-onprem-v2.3.0-Linux_x86_64.tar.gz
cd kafkaguard-onprem-v2.3.0/
The bundle contains everything you need:
kafkaguard-onprem-v2.3.0/
├── kafkaguard ← CLI binary
├── docker-compose.onprem.yml
├── env.onprem.example ← copy to .env.onprem and edit
├── installer/
│ ├── backup.sh
│ ├── restore.sh
│ ├── upgrade.sh
│ └── check-ports.sh
└── policies/
├── baseline-dev.yaml
├── enterprise-default.yaml
└── finance-iso.yaml
Step 2: Run the Installer
./installer/install.sh
The installer will prompt you for:
Before running the installer, get your license key at kafkaguard.com/pricing — self-serve checkout, delivered by email immediately after purchase. The key starts with
kg_.
- Host IP/hostname — the server address (default: localhost)
- Admin email — your admin login email
- Admin password — must be at least 12 characters
- Organization name — your company name
- License key — your
kg_...key from kafkaguard.com/pricing (or press Enter to run in Community mode) - TLS certificates — your own or auto-generated self-signed
⚠️ Password restriction: Do not use
$in passwords. Docker Compose interprets$as a variable prefix, silently truncating the password. Use letters, numbers, and symbols like! @ # % ^ & * - _ + = [ ] { }.
Step 3: Verify Installation
# Check all services are running
docker compose -f docker-compose.onprem.yml ps
# Check API health
curl -k https://localhost/health
All five services should show healthy. The API automatically:
- Creates the MinIO storage bucket on first start
- Generates RSA JWT keys and persists them — you never need to set
JWT_PRIVATE_KEYmanually
Step 4: Create Your Admin Account
Open your browser to http://your-server:3000. You will be redirected to a setup page. Fill in your organization name, admin email, and password, then click Create account.
Step 5: Log In
After account creation you are automatically signed in and land on the Clusters dashboard.
What Gets Created
| Component | Description |
|---|---|
| PostgreSQL | Database (data in kafkaguard_postgres-data volume) |
| Redis | Job queue (data in kafkaguard_redis-data volume) |
| MinIO | Object storage for raw scans (data in kafkaguard_minio-data volume) |
| API | Fastify REST API on port 3001 |
| Worker | BullMQ scan processor |
| Dashboard | Next.js UI on port 3000 |
| Nginx | TLS termination, ports 80/443 |
Upgrading
Important: Your Data is Safe
Upgrades never touch your data. All data is stored in Docker named volumes:
kafkaguard_postgres-data— database (clusters, scans, findings, users)kafkaguard_minio-data— raw scan JSON fileskafkaguard_redis-data— job queue state
These volumes persist across container restarts and upgrades. Only the application containers (API, worker, dashboard) are replaced.
Note: If you migrate to a new server, your license key works as-is — KafkaGuard licenses are not machine-bound. Just run
kafkaguard license activate --key kg_...on the new server after installation.
⚠️ Never run
docker compose down -vin production. The-vflag permanently deletes all named volumes — your entire database, all scan files, and all Redis state. Usedocker compose down(without-v) to stop services safely. To wipe data intentionally, run./installer/backup.shfirst.
Upgrade Steps
# 1. Extract the new version alongside the existing one
tar -xzf kafkaguard-onprem-v2.3.0.tar.gz
cd kafkaguard-onprem
# 2. Run the upgrade script
./installer/upgrade.sh
The upgrade script automatically:
- Creates a backup of your database and object storage
- Verifies data volumes exist
- Loads new Docker images from the bundle
- Rolling restarts API, worker, dashboard, nginx (not database/redis/minio)
- Runs database migrations at API startup
- Waits for health check to confirm the API is ready
Verify After Upgrade
# Check version
curl -k https://localhost/health
# Check all data is intact
curl -k https://localhost/api/v1/clusters -H "Authorization: Bearer <your-token>"
Rollback
If something goes wrong, restore from the auto-backup:
# List available backups
./installer/backup.sh list
# Restore the pre-upgrade backup
./installer/backup.sh restore backups/kafkaguard-backup-YYYYMMDD-HHMMSS
Air-Gapped Upgrade
For servers with no internet access, download the air-gapped bundle on a machine with internet, then transfer it:
On an internet-connected machine:
curl -LO https://github.com/KafkaGuard/kafkaguard-releases/releases/download/v2.3.0/kafkaguard-airgap-v2.3.0.tar.gz
# Transfer to air-gapped server via USB, SCP, or internal file share
On the air-gapped server:
tar -xzf kafkaguard-airgap-v2.3.0.tar.gz
cd kafkaguard-airgap-v2.3.0/
./airgap-upgrade.sh
The air-gapped bundle (~320 MB) contains:
- All 3 Docker images (pre-exported, loaded with
docker load) - Linux x86_64 CLI binary
docker-compose.onprem.ymlwith updated version tagsupgrade.shinstaller script- SHA256 checksums for integrity verification
Backup & Restore
Manual Backup
./installer/backup.sh backup
Creates a timestamped backup in ./backups/ containing:
db.sql— full PostgreSQL dumpminio-data/— all scan filesenv.bak— environment configurationmanifest.json— backup metadata
Restore
./installer/backup.sh restore backups/kafkaguard-backup-YYYYMMDD-HHMMSS
Scheduled Backups (Recommended)
Add to crontab for daily backups:
crontab -e
# Add this line for daily backup at 2 AM:
0 2 * * * /path/to/kafkaguard/installer/backup.sh backup /path/to/kafkaguard/backups
CLI Upgrade
The KafkaGuard CLI is a standalone binary — no data is stored locally. To upgrade:
Linux / macOS
# Download the latest release
curl -LO https://github.com/KafkaGuard/kafkaguard-releases/releases/latest/download/kafkaguard_$(uname -s)_$(uname -m).tar.gz
# Extract and replace
tar -xzf kafkaguard_*.tar.gz
sudo mv kafkaguard /usr/local/bin/kafkaguard
# Verify
kafkaguard version
Docker
docker pull kafkaguard/cli:latest
No Data Loss Risk
The CLI is stateless — it connects to Kafka, scans, and produces reports. Upgrading the binary has zero impact on:
- Your Kafka clusters
- Your On-Prem dashboard data
- Your scan history
- Your policies (YAML files you control)
Troubleshooting
Services won't start after upgrade
# Check logs
docker compose -f docker-compose.onprem.yml logs api --tail 50
docker compose -f docker-compose.onprem.yml logs worker --tail 50
# Check if migrations failed
docker compose -f docker-compose.onprem.yml logs api | grep -i "migration"
Database connection errors
# Verify postgres is healthy
docker compose -f docker-compose.onprem.yml exec postgres pg_isready -U kafkaguard
# Check volume exists
docker volume inspect kafkaguard_postgres-data
Rollback to previous version
# Restore from backup
./installer/backup.sh restore backups/<latest>
# Load old images if you still have the previous bundle
docker load -i /path/to/old-bundle/images/*.tar
docker compose -f docker-compose.onprem.yml up -d