c74461ddfbc1e73c0e258808c00259bd857e69f3
Revised table cell padding for better spacing and adjusted the hover effect on alert items to remove the slight upward translation. These changes aim to improve the UI consistency and user experience.
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_databasepg_stat_activitypg_stat_bgwriterpg_lockspg_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
- Authentication and RBAC (
- 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 applicationfrontend/React (Vite) applicationops/helper scripts and env template copydocker-compose.ymlfull stack definition.env.exampleenvironment 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 yourBACKEND_PORT) - core DB:
5433(or yourDB_PORT)
- frontend:
Optional but recommended:
psqlclient for troubleshooting target connectivity
Quick start
- Create local env file:
cp .env.example .env
- Generate an encryption key and set
ENCRYPTION_KEYin.env:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
- Start services:
make up
- Open:
- Frontend:
http://<SERVER_IP>:5173(orhttps://<your-domain>) - Backend API:
http://<SERVER_IP>:8000/api/v1(orhttps://<your-domain>/api/v1) - OpenAPI docs:
http://<SERVER_IP>:8000/docs(orhttps://<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/docsENVIRONMENT:dev | staging | prod | testLOG_LEVEL:DEBUG | INFO | WARNING | ERROR
Core database (internal)
DB_NAME: Internal metadata DB nameDB_USER: Internal metadata DB userDB_PASSWORD: Internal metadata DB passwordDB_PORT: Host port mapped to internal PostgreSQL5432
Backend API
BACKEND_PORT: Host port mapped to backend container8000JWT_SECRET_KEY: JWT signing key (must be changed)JWT_ALGORITHM: JWT algorithm (defaultHS256)JWT_ACCESS_TOKEN_MINUTES: access token lifetimeJWT_REFRESH_TOKEN_MINUTES: refresh token lifetimeENCRYPTION_KEY: Fernet key for encrypting target passwords at restCORS_ORIGINS: comma-separated allowed origins or*(dev-only)POLL_INTERVAL_SECONDS: collector polling intervalINIT_ADMIN_EMAIL: bootstrap admin emailINIT_ADMIN_PASSWORD: bootstrap admin password
Frontend
FRONTEND_PORT: Host port mapped to frontend container80VITE_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
- Proxy/SSL setup: use
API overview (minimum)
- Auth:
POST /api/v1/auth/loginPOST /api/v1/auth/refreshPOST /api/v1/auth/logoutGET /api/v1/me
- Targets:
GET/POST /api/v1/targetsGET/PUT/DELETE /api/v1/targets/{id}GET /api/v1/targets/{id}/metrics?from=&to=&metric=GET /api/v1/targets/{id}/locksGET /api/v1/targets/{id}/activityGET /api/v1/targets/{id}/top-queriesGET /api/v1/targets/{id}/overview
- Admin users (admin-only):
GET /api/v1/admin/usersPOST /api/v1/admin/usersPUT /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
Releases
12
Languages
Python
48.2%
JavaScript
40.1%
CSS
10.4%
Shell
0.5%
Dockerfile
0.5%
Other
0.2%