Percona Monitoring and Management (PMM) is a best-of-breed open source database monitoring solution. It helps you reduce complexity, optimize performance, and improve the security of your business-critical database environments, no matter where they are located or deployed. PMM helps users to:
- Reduce Complexity
- Optimize Database Performance
- Improve Data Security
See the PMM Documentation for more information.
This repo uses the following stack across its packages:
- pnpm (https://pnpm.io/)
- Turborepo (https://turborepo.com/)
- Typescript (https://www.typescriptlang.org/)
- React (https://react.dev/)
- Rollup to bundle the different common packages (https://rollupjs.org/)
- Vite for development (https://vitejs.dev/)
- Vitest for unit tests (https://vitest.dev/)
- pmm — main PMM UI application
- pmm-compat — Grafana plugin that handles communication between Grafana and PMM UI
- shared — common code between applications
The PMM devcontainer (see the root CONTRIBUTING.md) now ships Node 22 + pnpm (via Corepack) and a Vite dev server that runs end-to-end with the rest of PMM Server. From the repo root on the host:
make env-up # first run only; reuses the container afterwards
make env # shell into the containerThen inside the container:
make run-uirun-ui installs UI dependencies, symlinks the pmm-compat plugin into Grafana's plugin directory, injects livereload into Grafana's index.html (setup-livereload), and starts Vite on port 5173.
Open https://localhost/ — Grafana loads the pmm-compat plugin, which fetches the main UI from the Vite dev server. Edits under ui/apps/pmm/src/ hot-reload in the browser without a full page refresh.
Notes:
- The Vite port is configurable via
PMM_PORT_VITEin your.env(see.env.dev.example); it defaults to5173. run-uiinstalls an EXIT trap that restores the originalpmm-compat-appplugin and restarts Grafana when you Ctrl-C. Don't kill the container mid-run, or the restore is skipped.- For a one-shot build deployed into the container's system paths, use
make build-uiinstead.
The devcontainer ships a prebuilt Grafana baked into the perconalab/pmm-server dev image. To develop against a local percona/grafana fork instead, mount your checkout into the container and rebuild it:
-
Clone the Grafana fork next to the
pmmrepo on the host, so it resolves to../grafanafrom the repo root:git clone https://github.com/percona/grafana ../grafana
-
Uncomment the
grafanavolume mappings indocker-compose.dev.yml:# grafana - ../grafana:/root/go/src/github.com/percona/grafana - ../grafana/public:/usr/share/grafana/public
The first mount provides the Grafana source for the backend build; the second serves the fork's built frontend (
public/). -
Recreate the container so the new mounts take effect — volume mappings are read at container create time (
make env-downthenmake env-up, or recreate via your container tooling). -
Rebuild the Grafana backend inside the container:
make grafana-be-build
This runs
make build-goin/root/go/src/github.com/percona/grafana, copies the resultingbin/linux/amd64/grafanabinary to/usr/sbin/grafana, and restarts Grafana via supervisor.
For frontend changes in the fork, rebuild its public/ assets (make build-js inside the grafana checkout); they are served through the ../grafana/public mount.
Use this when you want to drive Vite from your IDE without make env. You still need a reachable PMM Server — the simplest way is to leave the devcontainer running (make env-up) so its ports are exposed; any other PMM Server reachable at https://localhost:8443 works too.
Prerequisites:
make setup # pnpm install across the workspace
make dev # turbo dev → Vite on https://localhost:5174 (or 5173 if nginx certs are present)Vite proxies /v1, /graph, and /logs.zip to the PMM Server (inside the devcontainer: https://localhost:8443; on the host when using the devcontainer-exposed ports: https://localhost) — see apps/pmm/vite.config.ts.
make buildmake test # vitest across the workspace
make lint
make format