Skip to content

Latest commit

 

History

History
308 lines (224 loc) · 16.2 KB

File metadata and controls

308 lines (224 loc) · 16.2 KB

Install

Application Prerequisites

Azimutt Inspector is a NodeJS application that can be deployed using:

It needs a database as storage, either PostgreSQL (production) or SQLite (in local, with a file, or in memory).

Managed Database Prerequisites

PostgreSQL

Azimutt Inspector uses pg, working with most PostgreSQL versions. See connection troubleshooting if you encounter any issue.

Create an azimutt user with minimal rights:

CREATE USER azimutt WITH PASSWORD 'your_password';
GRANT CONNECT ON DATABASE your_database TO azimutt;
GRANT pg_monitor TO azimutt;

If you have to grant access to many databases, you can use:

SELECT concat('GRANT CONNECT ON DATABASE "', datname, '" TO azimutt;') AS query FROM pg_database;

For cleanup, you can revoke the rights and drop the user:

REVOKE CONNECT ON DATABASE your_database FROM azimutt;
DROP USER azimutt;

For the best results, make sure to:

  • enable pg_stat_statements extension (probably enabled by default): track query execution statistics
  • enabled auto_explain extension: log the plan of slow queries
  • install pg_show_plans extension: allow to get the plan of a running query
  • extract an interesting sample of database logs
  • in Instance configuration, make sure to fill vCPU, RAM, and Storage properties (for settings tuning)

MySQL

Azimutt Inspector uses mysql2, working with most MySQL versions. See connection troubleshooting if you encounter any issue.

Create an azimutt user with minimal rights:

-- Create the user
CREATE USER 'azimutt'@'%' IDENTIFIED BY 'your_password';
-- Grant system access for monitoring
GRANT SELECT ON information_schema.* TO 'azimutt'@'%';
GRANT SELECT ON performance_schema.* TO 'azimutt'@'%';

For cleanup, you can revoke the rights and drop the user:

REVOKE SELECT ON information_schema.* FROM 'azimutt'@'%';
REVOKE SELECT ON performance_schema.* FROM 'azimutt'@'%';
DROP USER 'azimutt'@'%';

Connection Troubleshooting

If you have a database connection issue, there are troubleshooting tests:

  • open postgresql.test.ts or mysql.test.ts
  • find the connects test, remove the, and use your own database credentials
  • run it with npm test -w backend postgresql.test.ts -- -t connects (if you haven't already, run npm install first)
  • change connection parameters until it works

If you can't make it work, maybe Azimutt Inspector is missing a configuration for your case. You can try to connect directly with pg (doc) or mysql2:

  • below in the same file postgresql.test.ts (or mysql.test.ts)
  • find the connects raw test, remove the, and use your own database credentials
  • run it with npm test -w backend postgresql.test.ts -- -t "connects raw"
  • change connection parameters until it works

If you still can't make it work, ping us so we can troubleshoot together.

Application Setup

JavaScript runtime

For a production setup, use these two commands:

npm run build:prod
npm run start:prod

For full configuration, see Environment Variables.

Clever Cloud

  • Create a Node.js application
  • Setup required Environment variables
    • PORT=8080: required by Clever Cloud
    • CC_NODE_BUILD_TOOL=custom: to allow CC_CUSTOM_BUILD_TOOL
    • CC_CUSTOM_BUILD_TOOL=npm run build:prod: to build the app with dev dependencies
    • CC_RUN_COMMAND=npm run start:prod: to start the app in production mode
    • set needed environment variables
  • Add Clever Cloud git remote: git remote add clever git+ssh://git@push-n3-par-clevercloud-customers.services.clever-cloud.com/app_00000000-0000-0000-0000-000000000000.git
  • Push your code: git push clever your_branch:master
  • Open your app

Heroku

  • Create an app
  • Add Heroku git remote: heroku git:remote -a your_app_name
  • Push your code: git push heroku your_branch:main (custom start command configured in Procfile)
  • Open your app

Docker

Using the pre-built image:

# Run with your database URL (PostgreSQL example)
docker run --rm --pull always -p 3000:3000 -e QUICKSTART_DB=postgresql://user:password@host:5432/database --name inspector ghcr.io/azimuttapp/inspector:latest

Building the image yourself:

# Build the Docker image locally
docker build -t azimutt/inspector .

# Run with your database URL (PostgreSQL example)
docker run --rm -p 3000:3000 -e QUICKSTART_DB=postgresql://user:password@host:5432/database --name inspector azimutt/inspector

Docker networking note: When running in Docker, localhost refers to the container itself. To connect to a database on your host machine:

  • Linux: Use --network host flag: docker run --network host ...
  • Mac/Windows: Use host.docker.internal instead of localhost in the connection URL
  • Alternative: Use your machine's IP address instead of localhost

If you got: "Error response from daemon: Conflict. The container name "/inspector" is already in use", use docker rm -f inspector.

For full configuration, see Environment Variables.

Kubernetes

There is a Helm chart available for Kubernetes.

For full configuration, see Environment Variables.

Environment Variables

All variables are optional, Azimutt Inspector uses default values if not provided.

Variable Description Default
PORT Azimutt server port 3000
DATABASE_URL Azimutt own database, PostgreSQL or SQLite :memory:
DATABASE_ROLE Role to use for PostgreSQL storage if different from user -
DATABASE_POOL_MAX Max connections in pool for PostgreSQL storage 5
APP_SECRET Used to encrypt secrets in database (see Secret Rotation below) change-me
AUTH_JWT_SECRET Used to sign JWT tokens (see Secret Rotation below) change-me-change-me
AUTH_CACHE_DURATION Cache duration for auth roles/providers 1m
AUTH_EMERGENCY_USER Emergency only: Login bypass with full rights (see Security below) -
AUTH_EMERGENCY_PASS Emergency only: Password for emergency user -
SCHEDULER_START Start the scheduler when the application starts true
INSTANCE_TAG_FILTER Comma-separated tags to filter which instances this app manages (default: all) -
PLUGIN_FOLDERS Folders to load plugins from (comma-separated) -
RUNBOOK_FOLDERS Folders to load runbooks from (comma-separated) -
QUICKSTART_DB Auto create an instance and monitoring for this database -
QUICKSTART_CONF Path to JSON file for initial configuration (see below) -
LOG_LEVEL Log level (verbose, debug, log, warn, error, fatal) log
LOG_LEVEL_CONFIG Log level configuration (pattern:level, comma-separated) -
DIAG_EVENT_LOOP_BLOCKED Log event loop blocked detection threshold in ms -
LICENSE License key for Enterprise features (see docs/ee.md) -

⚠️ Security note: The default values for APP_SECRET and AUTH_JWT_SECRET are not secure. For any deployment beyond local testing, change them to strong random strings (e.g. openssl rand -hex 32). Using the defaults in production exposes your encrypted secrets and authentication tokens.

Secret Rotation

Both APP_SECRET and AUTH_JWT_SECRET support key rotation to allow updating secrets without downtime:

# Rotate APP_SECRET (for database encryption)
APP_SECRET="rotate:NEW_SECRET_KEY,OLD_SECRET_KEY"

# Rotate AUTH_JWT_SECRET (for JWT tokens)
AUTH_JWT_SECRET="rotate:NEW_JWT_SECRET,OLD_JWT_SECRET"

Important:

  • The first secret in the rotation list is used for new encryptions/signatures
  • Additional secrets are used as fallbacks for decryption/verification (you can have as many as you want, not just one)
  • Never remove a secret from the rotation list until all data encrypted/signed with it has been migrated
  • For APP_SECRET rotation: All database passwords, API keys, and sensitive config are encrypted with this key. Changing it without rotation will make all encrypted data unreadable.

Security

Emergency User: The AUTH_EMERGENCY_USER and AUTH_EMERGENCY_PASS provide a backdoor for system recovery when the normal authentication system is unavailable (e.g., locked out of all accounts, database issues).

⚠️ Security implications:

  • This user bypasses all authentication checks and has full admin/owner rights
  • Should only be configured temporarily for emergency recovery
  • All emergency user logins are logged for security audit
  • Remove these environment variables immediately after resolving the emergency

Quickstart Configuration

The QUICKSTART_DB environment variable allows you to create a database instance when none exists; useful for quick setup and testing.

The QUICKSTART_CONF environment variable allows you to bootstrap Azimutt Inspector with a complete configuration from a JSON file (settings, users, roles...); missing entities are created.

They can be used together, QUICKSTART_CONF taks precedence over QUICKSTART_DB, so if a database instance is defined in QUICKSTART_CONF, the one from QUICKSTART_DB is ignored.

QUICKSTART_CONF is useful for:

  • Automated deployments with predefined settings
  • Reproducing configurations across environments
  • Infrastructure as Code setups

The configuration file can define:

  • settings: Application settings (LLM context, server URL, observability, etc.)
  • roles: User roles with permissions
  • users: User accounts with role assignments
  • authProviders: Authentication providers (local, OAuth)
  • llmModels: LLM model configurations (OpenAI, Google, Ollama, etc.)
  • llmTools: Custom LLM tools (SQL queries, external integrations)
  • llmSystemPrompts: Custom system prompts for the AI assistant
  • collectors: Data collectors (built-in modules or custom SQL queries)
  • presets: Collector presets for easy instance configuration
  • analyzers: Analyzers for generating alerts and suggestions
  • notifiers: Notification channels (Slack, webhooks, etc.)
  • instances: Database instances to monitor

Environment variable substitution: Use $VAR_NAME syntax for sensitive values:

{
  "llmModels": [
    { "name": "gpt4", "provider": "openai", "model": "gpt-4", "apiKey": "$OPENAI_API_KEY" }
  ]
}

See quickstart-conf.example.json for a complete example.

Scaling

When monitoring a large number of database instances, a single Azimutt Inspector node may become a bottleneck (too many open connection pools). You can start several instances of Azimutt Inspector on the same storage, the load will be distributed across them.

You can go further with instance tag-based filtering to limit the opened connections to a subset of instances.

How it works:

  1. Tag each database instance with a group identifier (e.g. node-eu, node-us) from the instance settings page.
  2. Set the INSTANCE_TAG_FILTER environment variable on Azimutt Inspector nodes, they will schedule collectors only for instances with a matching tag, but also any analyzers and notifiers.

Recommended deployment topology for, say, 100 instances:

Node INSTANCE_TAG_FILTER SCHEDULER_START Role
eu-1 node-eu true Schedules collectors only for EU instances
eu-2 node-eu true Same, useful for redundancy
us-1 node-us true Schedules collectors only for US instances
us-2 node-us true Same, useful for redundancy
fallback (unset) true Schedules everything, including collectors with not matching tags
ui (unset) false UI-only, no scheduling (no CPU/RAM competition between UI & jobs)

Notes:

  • INSTANCE_TAG_FILTER is comma-separated, with OR semantics: node-eu,node-us matches instances tagged with either tag.
  • Nodes with no INSTANCE_TAG_FILTER manage all instances — use SCHEDULER_START=false if you want a UI-only node.
  • Analyzer, notifier, and retention jobs are global; all nodes compete for them via the shared queue (this is intentional).
  • The General Settings page shows the active tag filter under the Scheduler status section for the instance.

Production Checklist

Before deploying Azimutt Inspector to production, make sure to:

  • Change APP_SECRET: use a strong random string (openssl rand -hex 32). This encrypts all database passwords and API keys stored by Inspector. Losing or changing it without rotation makes all encrypted data unreadable.
  • Change AUTH_JWT_SECRET: use a different strong random string. This signs authentication tokens.
  • Setup storage: set DATABASE_URL to SQLite file for community and a PostgreSQL connection string in enterprise. In-memory SQLite (the default) loses all data on restart (only good for quick testing).
  • Enable authentication (Enterprise): configure auth providers to restrict access to your Inspector instance.
  • Create a dedicated database user: follow the PostgreSQL or MySQL setup above to grant minimal read-only rights to the database user provided to Azimutt Inspector.
  • Back Azimutt Inspector database: include the Azimutt Inspector database in your backup strategy. It holds your configuration, alert history, and execution logs.
  • Review security considerations: understand the security model, especially if exposing Inspector on a network.