Vigilant - Complete Documentation
Table of Contents
- Overview
- Architecture
- Installation & Building
- Usage
- Service Configuration
- Deployment
- Dashboard
- Advanced Features
- Troubleshooting
- Example Configurations
Overview
Vigilant is a lightweight, dynamic proxy server and service manager written in C++17. It combines four core functions:
- Reverse Proxy - Routes HTTP/WebSocket traffic to backend services
- Service Orchestrator - Manages service lifecycle and auto-sleep
- Deployment CLI - Deploy services from Git repos or .vig files
- Operations Dashboard - Live monitoring of traffic and system logs
Key Features
- Dynamic Reverse Proxy: Routes inbound traffic to backend services based on configured domains
- Service Lifecycle Management: Automatically stops services that have been inactive for a specified timeout to save resources
- Dashboard Functionality: Built-in dashboard server with real-time statistics and logs
- HTTPS/SSL Support: Native support for OpenSSL with SNI support for per-domain certificates
- WebSocket Support: Full bidirectional WebSocket proxying
- Hot Configuration Reload: Service configs are watched and reloaded without restart
- Rate Limiting: Per-service rate limiting support
- Git Deployments: Deploy apps directly from Git repositories with automatic runtime detection
Design Philosophy
Vigilant is designed strictly with performance, simplicity, and usefulness in mind. It targets businesses, SaaS platforms, and advanced homelab users who need a dynamic, lightweight, and completely transparent proxy and service manager.
Architecture
Request Lifecycle
When an incoming request arrives at Vigilant:
- Domain Extraction - Extract the host from request headers (X-Forwarded-Host or Host)
- Service Lookup - Find the service mapped to that domain
- Rate Limiting - Apply optional per-service rate limits
- Service Waking - If sleeping, start the service asynchronously
- Health Checking - Verify service is ready via health endpoint
- Proxying - Forward the request and relay responses
- Monitoring - Record request stats, latency, and bytes transferred
Component Model
┌─────────────────────────────────────────────────────────┐
│ Vigilant Daemon │
├────────────────────┬──────────────────┬─────────────────┤
│ Proxy Server │ Dashboard Server │ Config Watcher │
│ (Port 9000) │ (Port 9001) │ │
├────────────────────┼──────────────────┼─────────────────┤
│ Service Manager │
│ ├─ Service State Tracking │
│ ├─ Process Lifecycle (fork, exec, signal) │
│ ├─ Docker Lifecycle (run, start, stop) │
│ ├─ Health Check Loop │
│ └─ Reaper Thread (idle timeout logic) │
├────────────────────┬──────────────────┬─────────────────┤
│ Logging System │ Stats Manager │ CLI Commands │
│ (File + Console) │ (Metrics) │ (Deploy, List) │
└────────────────────┴──────────────────┴─────────────────┘
↓ (routes traffic to) ↓
┌─────────────────────────────────────────────────────────┐
│ Backend Services │
│ ├─ Service 1 (Process) - api.example.com:3001 │
│ ├─ Service 2 (Docker) - web.example.com:8080 │
│ └─ Service 3 (Docker) - worker.example.com:5000 │
└─────────────────────────────────────────────────────────┘
Service States
Each service has three possible states:
- SLEEPING - Service is not running, awaiting first request
- STARTING - Service is in startup phase, health checks in progress
- RUNNING - Service is active and handling traffic
A background reaper thread checks idle time every 30 seconds and puts idle services to sleep after the configured timeout period.
Installation & Building
Quick Install (Linux)
curl -sL vigi.sh/install | sudo bash
This downloads the latest Vigilant binary and installs it to your system path.
Download from GitHub
Pre-built binaries are available on the Vigilant releases page. Download the appropriate binary for your platform and place it in your path.
Building from Source
Prerequisites
- C++17 compatible compiler (GCC 8+, Clang 7+, MSVC 2019+)
- CMake (>= 3.10)
- Threads library
- OpenSSL (Optional, for Native HTTPS capabilities)
- Docker (Optional, for containerized service support)
Linux/macOS
git clone https://github.com/Zia-ullah-khan/Vigilant.git
cd Vigilant
mkdir build
cd build
cmake ..
cmake --build .
# Optionally install globally
sudo make install
Windows
git clone https://github.com/Zia-ullah-khan/Vigilant.git
cd Vigilant
mkdir build
cd build
cmake ..
cmake --build . --config Debug
# Executable will be at: build\Debug\vigilant.exe
Verify Installation
./vigilant --help
./vigilant_tests
Usage
Running the Daemon
The primary use is to run Vigilant as a daemon:
./vigilant [command] [options]
Server Command (Default)
Run the proxy server and service manager:
./vigilant server [options]
# Or simply: ./vigilant [options]
Options:
-d <dir>- Service config directory (default: /etc/vigilant/services)-p <port>- Listen port (default: 9000)-dash <port>- Dashboard listen port (default: 9001)-t <min>- Inactivity timeout in minutes (default: 10)-l <filepath>- Log file path (default: /var/log/vigilant.log, falls back to user-local)--cert <filepath>- Global SSL certificate file--key <filepath>- Global SSL key file-h, --help- Show help message
Example:
./vigilant server -p 8080 -dash 8081 -t 15 -d ./my_services_config
CLI Commands
Deploy a Service
Deploy a local .vig file:
./vigilant deploy ./myservice.vig
Deploy a Git repository:
./vigilant deploy https://github.com/user/app.git \
--branch main \
--domain myapp.example.com \
--port 8080
Deploy Options:
--branch <name>- Git branch to deploy--tag <name>- Git tag to deploy--commit <sha>- Git commit to deploy--domain <name>- Route domain override--port <num>- Service port (default: 8080)--dockerfile <path>- Dockerfile path relative to repo root--context <path>- Docker build context relative to repo root--container <name>- Docker container name override--build-arg <k=v>- Docker build arg (repeatable)--env <k=v>- Runtime env var (repeatable)
List Deployed Services
./vigilant ls
Output format: name <tab> domain <tab> -> localhost:port
Remove a Service
./vigilant rm myservice
The daemon will automatically spin it down.
View Service Logs
./vigilant logs myservice
Shows last 100 log lines. For Docker containers, shows Docker logs. For processes, shows stdout/stderr captured to temp logs.
Manage Systemd Service (Linux only)
./vigilant start # Start the systemd service
./vigilant restart # Restart the systemd service
Service Configuration
.vig File Format
Services are defined in simple key-value .vig files. Place them in the config directory (default: /etc/vigilant/services).
name = myservice
domain = api.example.com
port = 3001
type = process
command = cd /path/to/app && node server.js
pidfile = /var/run/myservice.pid
health = /health
timeout = 30
ratelimit = 0
cert = /etc/letsencrypt/live/api.example.com/fullchain.pem
key = /etc/letsencrypt/live/api.example.com/privkey.pem
Configuration Keys
Required Fields
| Key | Type | Description |
|---|---|---|
name | string | Logical name of the service (alphanumeric, no spaces) |
domain | string | Domain name to route to this service; used for SNI matching |
port | integer | Internal port where backend service listens |
type | string | Service type: process or docker |
Process Type Fields (Required when type=process)
| Key | Type | Description |
|---|---|---|
command | string | Command to execute to start the service |
pidfile | string | Path to store process ID file (default: /var/run/{name}.pid) |
Docker Type Fields (Required when type=docker)
| Key | Type | Description |
|---|---|---|
image | string | Docker image name:tag |
container | string | Docker container name |
Optional Fields
| Key | Type | Default | Description |
|---|---|---|---|
health | string | / | Health check endpoint path |
timeout | integer | 30 | Service startup timeout in seconds |
ratelimit | integer | 0 | Rate limit in requests/minute (0 = unlimited) |
cert | string | - | Path to SSL certificate for this domain |
key | string | - | Path to SSL private key for this domain |
Git Deployment Metadata Fields
When deployed via Git, these are automatically added:
| Key | Type | Description |
|---|---|---|
sourcerepo | string | Git repository URL |
sourcebranch | string | Git branch (if deployed with --branch) |
sourcetag | string | Git tag (if deployed with --tag) |
sourcecommit | string | Resolved commit SHA |
buildcontext | string | Docker build context path |
dockerfile | string | Dockerfile path |
env | string | Runtime environment variables (repeatable) |
Configuration Examples
Process Service (Node.js)
name = api
domain = api.example.com
port = 3001
type = process
command = cd /home/app && npm start
pidfile = /tmp/api.pid
health = /health
timeout = 30
Docker Service
name = web
domain = web.example.com
port = 8080
type = docker
image = myregistry/web:latest
container = web-prod
health = /healthz
timeout = 45
ratelimit = 500
Service with HTTPS
name = secure
domain = secure.example.com
port = 3443
type = process
command = /opt/app/run.sh
pidfile = /var/run/secure.pid
cert = /etc/letsencrypt/live/secure.example.com/fullchain.pem
key = /etc/letsencrypt/live/secure.example.com/privkey.pem
Deployment
Local Service Deployment
- Create a .vig file describing your service:
name = myapp
domain = myapp.local
port = 8000
type = process
command = cd /path/to/myapp && python app.py
- Deploy it:
./vigilant deploy ./myapp.vig -d /etc/vigilant/services
- Vigilant will automatically pick it up and make it available at the configured domain.
Git-based Deployment
Deploy a GitHub repository directly:
./vigilant deploy https://github.com/user/my-app.git \
--branch main \
--domain myapp.example.com \
--port 8080
The deployment workflow:
- Clone the repository and checkout the specified branch/tag/commit
- Detect Runtime - Looks for package.json (Node), requirements.txt (Python), or Dockerfile
- Build Docker Image (if Docker available and Dockerfile exists)
- Fallback to Process Mode (if Docker not available or build fails)
- Generate .vig Config with deployment metadata
- Atomically Write config to services directory
- Auto-Spin Up on first request
Node.js Auto-Build
If no Dockerfile is found but package.json exists:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi
COPY . .
RUN npm run build --if-present
EXPOSE 8080
CMD ["npm", "start"]
Python Auto-Build
If no Dockerfile is found but requirements.txt exists:
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt* ./
RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
COPY . .
EXPOSE 8080
CMD ["python", "app.py"]
Reverse Proxy Setup with Nginx
Vigilant can run behind Nginx for additional features like rate limiting, caching, or TLS termination.
server {
listen 80;
server_name *.example.com;
location / {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 60s;
proxy_connect_timeout 60s;
}
}
For HTTPS:
server {
listen 443 ssl http2;
server_name *.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 300s;
proxy_connect_timeout 60s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Dashboard
Accessing the Dashboard
The dashboard is available at http://localhost:9001 (default) or the port specified with -dash.
Dashboard Interface
The dashboard displays:
- Total Requests - Cumulative count of all proxied requests
- Blocked (DDoS) - Count of rate-limited requests
- Traffic Served - Total bytes transferred in MB
- Live Traffic Panel - Last 100 requests with method, domain, path, status, latency
- System Logs Panel - Last 150 log entries (INFO/WARN/ERROR)
All data updates every 1 second via the /api/stats endpoint.
API Endpoint
GET /api/stats
Returns JSON:
{
"totalRequests": 12345,
"blockedRequests": 23,
"bytesTransferred": 5242880,
"recentRequests": [
{
"time": "14:23:45",
"method": "POST",
"domain": "api.example.com",
"path": "/users",
"status": 201,
"latencyMs": 145
}
],
"recentLogs": [
{
"time": "14:23:44",
"level": "INFO",
"message": "Service awake: myservice"
}
]
}
Advanced Features
HTTPS and TLS
Global Certificate
Serve HTTPS with a single certificate for all domains:
./vigilant server \
--cert /path/to/cert.pem \
--key /path/to/key.pem \
-p 9000
Per-Domain Certificates (SNI)
Each service can have its own certificate:
name = api
domain = api.example.com
port = 3001
type = process
command = npm start
cert = /etc/letsencrypt/live/api.example.com/fullchain.pem
key = /etc/letsencrypt/live/api.example.com/privkey.pem
Vigilant uses the TLS Server Name Indication (SNI) to route to the correct certificate.
WebSocket Support
Vigilant fully supports WebSocket proxying with bidirectional streaming. Simply configure a domain and Vigilant will upgrade HTTP connections to WebSocket automatically.
Example test:
# Terminal 1: Start a WebSocket server on localhost:8000
node websocket-server.js
# Terminal 2: Create a service
# (in /etc/vigilant/services/ws.vig):
# name = ws
# domain = ws.example.com
# port = 8000
# type = process
# command = node websocket-server.js
# Terminal 3: Connect via Vigilant
wscat -c ws://ws.example.com
Rate Limiting
Limit requests per minute per service:
name = api
domain = api.example.com
port = 3001
type = process
command = npm start
ratelimit = 1000
Rate limiting is per IP+domain combination. When exceeded, client receives HTTP 429 (Too Many Requests).
Hot Configuration Reload
Configuration changes are detected automatically every 5 seconds:
- Service added - Loaded and made available
- Service updated - Config reloaded; service restarted if critical fields changed
- Service removed - Service stopped and unregistered
Critical fields that trigger restart: port, command, image, container, type
Service Idle Timeout
Set the global inactivity timeout:
./vigilant server -t 15 # 15 minutes
Services automatically sleep after this period of inactivity. Default is 10 minutes.
Logging
Vigilant logs to file and console. Logs include all system events, service lifecycle changes, and request errors.
Log locations (in order of preference):
- Specified path:
-l /custom/path/vigilant.log - System log dir:
/var/log/vigilant.log - User local:
$HOME/.local/state/vigilant/vigilant.log(Linux) or%LOCALAPPDATA%\Vigilant\logs\vigilant.log(Windows) - Current directory:
./vigilant.log
Troubleshooting
Service Won't Start
Check the logs:
./vigilant logs myservice
Common causes:
- Binary/command not found - Verify path is absolute and executable
- Port already in use - Change service port or kill existing process
- Permission denied - Check file permissions and user privileges
- Docker image not found - Verify image exists:
docker images
Health Check Timeout
Increase the timeout value in .vig:
timeout = 60 # Increase to 60 seconds
Ensure the health endpoint is responding correctly.
WebSocket Connection Fails
Ensure:
- Backend is listening for WebSocket upgrades
- No proxies between client and Vigilant are blocking upgrade headers
- Service is actually running (check via dashboard)
Rate Limiting Too Aggressive
Adjust the rate limit:
ratelimit = 10000 # Higher = more permissive
Monitor via dashboard to tune appropriately.
Port Already in Use
Change the proxy port:
./vigilant server -p 9002
Or kill the existing process:
# Find process using port 9000
lsof -i :9000
kill -9 <PID>
Dashboard Not Accessible
Verify the dashboard port:
./vigilant server -dash 9002 # Different port
Check that the port isn't blocked by firewall.
Config Not Reloading
Ensure the config directory is writable and Vigilant has permissions. Config changes take effect within 5 seconds.
Test by modifying a .vig file and checking the logs.
Example Configurations
Single Node.js API
File: /etc/vigilant/services/api.vig
name = api
domain = api.example.com
port = 3001
type = process
command = cd /opt/api && npm start
pidfile = /var/run/api.pid
health = /health
timeout = 30
cert = /etc/letsencrypt/live/api.example.com/fullchain.pem
key = /etc/letsencrypt/live/api.example.com/privkey.pem
Start Vigilant:
./vigilant server -p 9000 -dash 9001 -d /etc/vigilant/services
Multi-Service Deployment
API Service
name = api
domain = api.mycompany.com
port = 3001
type = process
command = cd /opt/api && npm start
health = /health
timeout = 30
Web UI
name = web
domain = mycompany.com
port = 3000
type = docker
image = mycompany/web:latest
container = web-prod
health = /
timeout = 45
Database Migration Service
name = db-migrations
domain = internal.mycompany.com
port = 5000
type = process
command = ./db-migrate.sh
timeout = 120
Start:
./vigilant server \
-p 9000 \
-dash 9001 \
-t 20 \
-d /etc/vigilant/services
Docker Compose Integration
While Vigilant isn't a replacement for Docker Compose, you can use it alongside:
File: docker-compose.yml
version: '3'
services:
api:
image: myapp/api:latest
ports:
- "3001:3001"
environment:
NODE_ENV: production
File: /etc/vigilant/services/api.vig
name = api
domain = api.example.com
port = 3001
type = docker
image = myapp/api:latest
container = api-prod
health = /health
Real-World Example Services
24Control Backend
# File: 24controlapi.vig
name = 24control
domain = 24controlapi.rfas.software
port = 3001
type = process
command = cd /home/pi/Desktop/Projects/24Control/backend && node server.js
pidfile = /tmp/24control.pid
health = /
timeout = 30
cert = /etc/letsencrypt/live/24controlapi.rfas.software/fullchain.pem
key = /etc/letsencrypt/live/24controlapi.rfas.software/privkey.pem
RoboTrader (Docker)
# File: robotrader.vig
name = robotrader
domain = robotrader.rfas.software
port = 8083
type = docker
image = robotrader:latest
container = robotrader-container
health = /ping
timeout = 30
StudySync (Docker)
# File: studysync.vig
name = studysync
domain = studysync.rfas.software
port = 8081
type = docker
image = studysync:latest
container = studysync-container
health = /health
timeout = 30
Run all three:
./vigilant server \
-d /etc/vigilant/services \
-p 9000 \
-dash 9001 \
-t 10
Vision & Roadmap
Vigilant is designed strictly with performance, simplicity, and usefulness in mind.
Current Capabilities
✅ Dynamic reverse proxy with domain-based routing
✅ Process and Docker service support
✅ Automatic service waking and sleeping
✅ HTTPS/TLS with SNI support
✅ WebSocket proxying
✅ Hot configuration reload
✅ Rate limiting
✅ Built-in dashboard with stats
✅ Git-based deployments
✅ CLI service management
Future Roadmap
- Enhanced Deployment - Support for deployment hooks and webhooks
- Metrics Export - Prometheus-compatible metrics endpoint
- Service Health Dashboard - Visual service status indicators
- Load Balancing - Multiple backend instances per domain
- Request Filtering - Custom middleware/plugins
- Performance Profiling - Built-in performance analytics
License
Vigilant is currently developed as a proprietary, closed-source solution intended for commercial licensing.
For commercial use or licensing inquiries, please contact the development team.