nessi 2747e62ff8 Rename migration revision ID for clarity
The migration script's revision ID was adjusted to remove redundancy in the naming. This improves readability and ensures consistency with naming conventions.
2026-02-12 13:41:48 +01:00
2026-02-12 09:09:13 +01:00
2026-02-12 08:12:57 +01:00
2026-02-12 09:09:13 +01:00
2026-02-12 09:09:13 +01:00

NexaPG - PostgreSQL Monitoring Stack

NexaPG is a Docker-based PostgreSQL monitoring platform for multiple remote targets, built with FastAPI + React.

What it includes

  • Multi-target PostgreSQL monitoring (remote instances)
  • Polling collector for:
    • pg_stat_database
    • pg_stat_activity
    • pg_stat_bgwriter
    • pg_locks
    • pg_stat_statements (if enabled on target)
  • Core metadata database for:
    • Authentication and RBAC (admin, operator, viewer)
    • Monitored target configuration (encrypted credentials)
    • Metrics and query stats
    • Audit logs
  • JWT auth (access + refresh)
  • FastAPI + SQLAlchemy async + Alembic migrations
  • React (Vite) frontend with:
    • Login/logout
    • Dashboard overview
    • Target detail with charts and database overview
    • Query insights
    • Admin user management
  • Health endpoints:
    • /api/v1/healthz
    • /api/v1/readyz

Repository structure

  • backend/ FastAPI application
  • frontend/ React (Vite) application
  • ops/ helper scripts and env template copy
  • docker-compose.yml full stack definition
  • .env.example environment template

Prerequisites

Install these before starting:

  • Docker Engine 24+
  • Docker Compose v2+
  • GNU Make (optional, for make up/down/logs/migrate)
  • Open ports on your host:
    • frontend: 5173 (default)
    • backend: 8000 (or your BACKEND_PORT)
    • core DB: 5433 (or your DB_PORT)

Optional but recommended:

  • psql client for troubleshooting target connectivity

Quick start

  1. Create local env file:
cp .env.example .env
  1. Generate an encryption key and set ENCRYPTION_KEY in .env:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
  1. Start services:
make up
  1. Open:
  • Frontend: http://<SERVER_IP>:5173 (or https://<your-domain>)
  • Backend API: http://<SERVER_IP>:8000/api/v1 (or https://<your-domain>/api/v1)
  • OpenAPI docs: http://<SERVER_IP>:8000/docs (or https://<your-domain>/docs)

Default initial admin (from .env):

  • Email: admin@example.com
  • Password: ChangeMe123!

Common commands

make up        # build + start all services
make down      # stop all services
make logs      # follow logs
make migrate   # run Alembic migrations in backend container

Environment variables reference

All variables are defined in .env.example.

Application

  • APP_NAME: Display name used by backend/docs
  • ENVIRONMENT: dev | staging | prod | test
  • LOG_LEVEL: DEBUG | INFO | WARNING | ERROR

Core database (internal)

  • DB_NAME: Internal metadata DB name
  • DB_USER: Internal metadata DB user
  • DB_PASSWORD: Internal metadata DB password
  • DB_PORT: Host port mapped to internal PostgreSQL 5432

Backend API

  • BACKEND_PORT: Host port mapped to backend container 8000
  • JWT_SECRET_KEY: JWT signing key (must be changed)
  • JWT_ALGORITHM: JWT algorithm (default HS256)
  • JWT_ACCESS_TOKEN_MINUTES: access token lifetime
  • JWT_REFRESH_TOKEN_MINUTES: refresh token lifetime
  • ENCRYPTION_KEY: Fernet key for encrypting target passwords at rest
  • CORS_ORIGINS: comma-separated allowed origins or * (dev-only)
  • POLL_INTERVAL_SECONDS: collector polling interval
  • INIT_ADMIN_EMAIL: bootstrap admin email
  • INIT_ADMIN_PASSWORD: bootstrap admin password

Frontend

  • FRONTEND_PORT: Host port mapped to frontend container 80
  • VITE_API_URL: API base URL baked into frontend build
    • Proxy/SSL setup: use /api/v1
    • Direct server setup: use http://<SERVER_IP>:<BACKEND_PORT>/api/v1

API overview (minimum)

  • Auth:
    • POST /api/v1/auth/login
    • POST /api/v1/auth/refresh
    • POST /api/v1/auth/logout
    • GET /api/v1/me
  • Targets:
    • GET/POST /api/v1/targets
    • GET/PUT/DELETE /api/v1/targets/{id}
    • GET /api/v1/targets/{id}/metrics?from=&to=&metric=
    • GET /api/v1/targets/{id}/locks
    • GET /api/v1/targets/{id}/activity
    • GET /api/v1/targets/{id}/top-queries
    • GET /api/v1/targets/{id}/overview
  • Admin users (admin-only):
    • GET /api/v1/admin/users
    • POST /api/v1/admin/users
    • PUT /api/v1/admin/users/{user_id}
    • DELETE /api/v1/admin/users/{user_id}

Security notes

  • No secrets are hardcoded in source
  • Passwords are hashed with Argon2
  • Target credentials are encrypted with Fernet
  • CORS is environment-configurable
  • Audit logs include auth, target, and user management events
  • Rate limiting is currently a placeholder for future middleware integration

Important: pg_stat_statements

Query Insights requires pg_stat_statements on each monitored target.

CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

Reverse proxy and SSL

For production-like deployments behind HTTPS:

  • Set frontend API to relative path: VITE_API_URL=/api/v1
  • Route /api/ from proxy to backend service
  • Keep frontend and API on the same public origin to avoid CORS/mixed-content problems
Description
No description provided
Readme 3 MiB
Languages
Python 48.2%
JavaScript 40.1%
CSS 10.4%
Shell 0.5%
Dockerfile 0.5%
Other 0.2%