Overview
Shieldome can be deployed on any Linux server you control - a VPS, a bare-metal machine, or a private cloud instance. The on-premise edition runs the same engine as the hosted service, but all data stays on your infrastructure. A license key is required for production use; contact [email protected] to obtain one.
Requirements
- Docker 24+ and Docker Compose v2+ (
docker composecommand) - A server with at least 2 GB RAM and 10 GB free disk space
- A domain name pointed at your server's IP (required for HTTPS and OOB detection)
- Ports 80 and 443 open in your firewall (for the reverse proxy)
- An on-premise license key - contact [email protected]
Quick start
1. Get the files
Clone the repository or download the release archive:
git clone https://github.com/shieldome/scanner.git
cd scanner
# Or pull the pre-built image without the source:
mkdir shieldome-onprem && cd shieldome-onprem
curl -O https://raw.githubusercontent.com/shieldome/scanner/main/docker-compose.yml
curl -O https://raw.githubusercontent.com/shieldome/scanner/main/.env.example
2. Configure environment
cp .env.example .env
# Open .env in your editor and fill in the required values
nano .env
At minimum, set these five values before starting:
SHIELDOME_SECRET_KEY- generate a strong random key (see below)POSTGRES_PASSWORD- set a strong database passwordDATABASE_URL- uncomment and update with your Postgres passwordAPP_BASE_URL- your public domain, e.g.https://scan.example.comLICENSE_KEY- your on-premise license key
# Generate a secure secret key python -c "import secrets; print(secrets.token_hex(32))"
3. Start the stack
docker compose up -d
This starts PostgreSQL, Redis, the Shieldome app, and the Celery background workers. First boot may take 30–60 seconds as images are pulled and the database is initialised. Check that all services are running:
docker compose ps docker compose logs -f shieldome
Once healthy, the app is reachable on port 5000. You should place it behind a reverse proxy (see SSL/HTTPS setup below) before exposing it to the internet.
Environment variables
| Variable | Required | Description |
|---|---|---|
SHIELDOME_SECRET_KEY |
Yes | Flask session secret. Generate with secrets.token_hex(32). Never use the default in production. |
DATABASE_URL |
Yes (prod) | PostgreSQL DSN, e.g. postgresql://shieldome:pass@postgres:5432/shieldome. Leave blank to use SQLite (single-container only). |
POSTGRES_DB |
Yes | PostgreSQL database name (used by the postgres Docker service). Default: shieldome. |
POSTGRES_USER |
Yes | PostgreSQL username. Default: shieldome. |
POSTGRES_PASSWORD |
Yes | PostgreSQL password. Must be set explicitly - Docker Compose will refuse to start without it. |
REDIS_URL |
Yes | Redis connection URL for Celery workers. Default: redis://redis:6379/0. |
APP_BASE_URL |
Yes | Public URL of your instance (no trailing slash). Used in emails, OAuth callbacks, and report links. |
RESEND_API_KEY |
Recommended | Resend API key for transactional email (alerts, account verification). Get a free key at resend.com. |
SHIELDOME_NOTIFY_EMAIL |
Recommended | Admin email for internal notifications (new tickets, abuse reports, etc.). |
INTERNAL_SECRET |
OOB only | Shared secret for authenticating OOB DNS callbacks. Generate with secrets.token_hex(32). |
OOB_DNS_DOMAIN |
OOB only | DNS subdomain for out-of-band detection probes, e.g. oob.scan.example.com. Omit to disable OOB detection. |
LICENSE_KEY |
Yes (prod) | On-premise license key. Contact [email protected] to obtain one. |
NVD_API_KEY |
Optional | NIST NVD API key - raises CVE lookup rate limit from 5/30s to 50/30s. Free at nvd.nist.gov. |
FLASK_ENV |
Optional | Set to production (default) or development. Never run development in production. |
See .env.example in the repository for the complete list including email, webhook, payment, and scanner tuning variables.
SSL/HTTPS setup
Run Shieldome behind a reverse proxy that handles TLS termination. Two common options:
Option A - Caddy (recommended, auto-HTTPS)
Caddy automatically obtains and renews Let's Encrypt certificates.
scan.example.com {
reverse_proxy localhost:5000
}
# Install Caddy (Debian/Ubuntu) sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update && sudo apt install caddy # Place your Caddyfile at /etc/caddy/Caddyfile, then: sudo systemctl reload caddy
Option B - nginx + Certbot
server {
listen 80;
server_name scan.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name scan.example.com;
ssl_certificate /etc/letsencrypt/live/scan.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/scan.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Required for Server-Sent Events (live scan progress)
proxy_buffering off;
proxy_read_timeout 300s;
}
}
sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d scan.example.com
proxy_buffering off directive is required for Server-Sent Events (real-time scan progress) to work correctly through nginx.
Updating
To pull the latest Shieldome image and restart with zero downtime:
docker compose pull docker compose up -d
Docker Compose will restart only the services whose images have changed. Database migrations run automatically on startup.
Backups
Back up the PostgreSQL database regularly. A simple daily dump:
# Create a timestamped dump docker compose exec postgres pg_dump -U shieldome shieldome \ > backup-$(date +%Y%m%d-%H%M%S).sql # Restore from a dump docker compose exec -T postgres psql -U shieldome shieldome \ < backup-20260101-120000.sql
Also back up the shieldome-reports Docker volume (or the ./reports directory if you use a bind mount) to preserve generated PDF reports.
OOB detection setup
Out-of-band (OOB) detection finds vulnerabilities - like blind SSRF and blind SQLi - that produce no visible response. Shieldome sends probes with unique DNS hostnames; if the target resolves them, a callback hits your OOB listener and the finding is confirmed.
To enable OOB detection on your self-hosted instance:
- Create a DNS A record pointing a wildcard subdomain at your server IP:
DNS
*.oob.scan.example.com A 203.0.113.10 (your server IP)
- Set
OOB_DNS_DOMAIN=oob.scan.example.comin your.env. - Set
INTERNAL_SECRETto a strong random value (used to authenticate callbacks). - Restart the stack:
docker compose up -d
Shieldome's built-in DNS listener starts automatically when OOB_DNS_DOMAIN is configured. No additional software is required.
License key
On-premise deployments require a license key set as LICENSE_KEY in your .env. The app will start without a key in evaluation mode (limited scans per day); production use requires a valid license.
To obtain a license key, contact [email protected] with your company name and expected scan volume. Licenses are per-installation and tied to your APP_BASE_URL.