# Pika: probe monitoring with tamper protection built in

> Pika is a Go probe monitoring system. Probes push metrics to the server over a websocket, VictoriaMetrics keeps the time series, and Postgres or SQLite keeps the rest. What separates it from a normal metrics stack is the second half of the feature list: file system watching for tampering, an immutable attribute patrol, an asset inventory with risk grading, and an audit history.

**pika-monitor/pika** — Lightweight probe monitoring — Go + VictoriaMetrics + PostgreSQL/SQLite | Real-time metrics, service checks, tamper protection & security audit

- Repository: https://github.com/pika-monitor/pika
- Website: https://pika.termark.app
- Stars: 642 · Forks: 83
- Language: Go
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/pika-monitor-pika

## Monitoring, and the part that is not monitoring

Pika is described as a lightweight probe monitoring system, and the architecture is in the overview sentence. Probes push metrics to the server over a websocket, VictoriaMetrics stores the time series, and Postgres or SQLite stores the business data.

The pull model of most monitoring is the thing this inverts. Instead of the server scraping each host, each host keeps a connection open to the server and pushes. That has a practical consequence for the operator, because the server no longer has to reach into the network where the machines are, and a probe behind a NAT or a firewall needs an outbound connection rather than an inbound one.

The second half of the overview is the part that makes Pika more than a metrics pipeline. Beyond monitoring it provides Linux incident response and baseline checks to surface security risks early.

The feature list is six groups. Real-time metrics cover processor, memory, disk, network, graphics, and temperature readings, with history over several ranges. Service checks cover HTTP and HTTPS, TCP, and ICMP, and they include certificate expiry detection, which is the kind of check that is trivial to add and saves a genuine outage. Tamper protection covers a file system watch, a patrol of the immutable attribute, and alerting. The security audit covers an asset inventory, risk grading on a four level scale from critical down to low, and an audit history.

Authentication is the fifth group, and deployment is the sixth. So the product is a monitoring system with a security module attached, and the screenshots in the readme are arranged in three columns, public, security, and tamper, which is a fair summary of what the interface is about.

The project is Apache 2.0 licensed, written in Go, and the site is pika.termark.app. There were three releases in the second half of 2026, and the documentation is split into a features page and two deployment guides.

## Why there are two databases

The split between VictoriaMetrics and a relational database is the design decision that shapes everything else, and it is a common one.

Time series and business data are not the same kind of data. A metric is a stream of numbers with a timestamp, written constantly, queried as ranges and rates, and kept for a bounded time. A login event, an asset record, a risk grade, an audit entry is written rarely, queried by identity, and kept because it is a record rather than a sample.

Putting both in one database means one of the two is served badly. Putting them in two means two things to run, and that is the cost VictoriaMetrics and Postgres or SQLite pays.

The Go dependencies show the choice being made. The database access goes through an object relational mapper with drivers for both Postgres and SQLite, and the SQLite driver is a pure Go one rather than the C library, which matters because the build sets the C cross compilation off and the container image is Alpine based. A C library would have broken that.

The same section of the dependency list explains the rest of the stack. There is a web framework for the interface and the API, a websocket library for the push channel, a JWT library and an OpenID Connect client for the authentication, a cron library for the scheduled work, a system metrics library for reading the processor, memory, disk, and network counters on a probe, a database client for the GeoIP lookups, a self update library, a service manager library for running as a system service, a backoff library, and a mail library with a rotating log writer for sending alerts.

The theme of the dependency list is a system that expects to run unattended on a small number of machines and to keep running for a long time without much attention.

## The checks, and the tampering detection

The service checks cover the three protocols a monitoring system actually needs. HTTP and HTTPS for the thing you care about, TCP for a port that should be open, and ICMP for whether the host is there at all.

The certificate expiry check is the detail worth pulling out, because it is the check people forget to set up and then regret. A certificate that expires on a Sunday night takes a service down at the least convenient moment, and detecting it in advance is a scheduled job rather than an incident.

The tamper protection is the part with no equivalent in a normal monitoring product, and it has three mechanisms.

The first is a file system watch, implemented with the same notification library that watches for changes to files, and it fires when something a probe watches is modified. On a host where a configuration file should not change, that is an intrusion signal.

The second is a patrol of the immutable attribute. On Linux, marking a file immutable prevents it being modified even by root, and a security tool that checks whether the sensitive files still carry that attribute is checking for a very specific kind of tampering, which is the kind where an attacker with root removes the protection first.

The third is alerting on the findings from the first two.

The security audit is the other half. It keeps an inventory of the assets, it grades the risk of what it finds on a scale from critical to low, and it keeps a history, so a change in grade over time is itself a record. The combination of an inventory, a grade, and a history is what makes it an audit rather than a check, and it is why the readme calls the feature a security audit and not just a check.

## Deploying it, and the credentials you must change

The quick start is the same shape for both database options, and it is deliberately short.

```bash
curl -O https://raw.githubusercontent.com/pika-monitor/pika/main/docker-compose.sqlite.yml
curl -o config.yaml https://raw.githubusercontent.com/pika-monitor/pika/main/config.sqlite.yaml
# Edit config.yaml: change JWT secret and admin password
docker compose -f docker-compose.sqlite.yml up -d
# Open http://localhost:8080  — default admin / admin123
```

Two files are fetched, a compose file and a configuration file, and then the only editing step is in the configuration: the JSON web token secret and the administrator password. The interface is on port 8080.

The PostgreSQL route is the same, with the compose and configuration files for that database, and one extra line in the edit instruction, because the database password is in the configuration too.

The default administrator credentials are printed in the readme, and they are the same for every installation. That is the one thing to fix before the service is reachable by anything else, and the readme puts it in the comment line of the quick start rather than in a warning, which is a good reason to read the comment.

The requirements are Docker 20.10 or newer and Docker Compose 1.29 or newer, or the version 2 plugin, and the compose files are the modern one with the services and the environment file, which means the same configuration file drives both deployment options.

The documentation is split into a features page, a deployment guide per database, and a common configuration page, and the readme links the community channels from the project site rather than listing them, which suggests a wiki and a chat rather than a mailing list.

## The build, the agent, and the separate themes

The build file is where the shape of the project becomes clear, because it treats the server, the agent, and the interface as three separate things with their own versions.

The version number comes from the git description, so a build is stamped with the tag it was built from, and there is a second version, for the agent, generated from the short hash of the last commit that touched the agent package. That is a small but meaningful detail: the agent and the server are versioned independently, which is what you need when the probe and the server are deployed separately and the server has to accept probes built at different times.

The linker flags strip the binary and stamp both version values into it, and the cross compilation is turned off, so the binaries are static. The server target builds for Linux on the 64 bit architecture with the path trimming enabled.

The container image is a single stage build on Alpine, and its comments explain the arrangement. The Dockerfile assumes the build artefacts were produced outside, and it copies in the binary for the target architecture, the agents directory, the built web interface, and the themes. The time zone data is installed and the time zone set, the port is exposed, and the entry point runs the server with the serve subcommand.

The themes are the most interesting part. There is a target that builds the official management interface and a separate default theme, and the default theme is not in the repository. It is cloned from a separate repository, checked for a package lock file and a theme manifest, built with npm, and then its manifest and its built output are copied into a themes directory in the release. So the interface is a separate project with its own build, and the server is designed to serve whatever theme is present.

That is a sensible split for a product whose interface is expected to change faster than its engine, and it explains the directory layout with a web folder, a playground, and a scripts directory alongside the Go code.

## Conclusion

Pika fits a small operations team that wants a self-hosted monitor for a handful of machines, with an audit trail rather than a wall of dashboards, and that would rather run two containers than run a monitoring platform. It does not fit a fleet large enough to need a proper time series database with retention policies, and it does not fit an organisation that needs its metrics in an existing stack. Verify first that the probes can reach the server over a websocket through whatever sits in between, that the default administrator password is changed before anything else, and that the tamper detection settings match how your hosts are actually managed, because an immutable file patrol is only useful if the files it watches are supposed to be immutable.

## FAQ

### What is the Pika monitoring system?

It is a lightweight probe monitoring system in Go. Probes push metrics to the server over a websocket, VictoriaMetrics stores the time series, and Postgres or SQLite stores the business data, and beyond monitoring it provides Linux incident response and baseline checks to surface security risks early.

### What does the tamper protection in Pika do?

It has three parts: a file system watch that fires when watched files are modified, a patrol of the immutable file attribute, which detects a host where the protection on sensitive files has been removed, and alerting on the findings.

### How do I deploy Pika?

Fetch a compose file and a configuration file, edit the configuration to change the token secret and the administrator password, and bring the stack up with Docker Compose. There is a variant for SQLite and one for PostgreSQL, the interface is on port 8080, and Docker 20.10 or newer and Compose 1.29 or newer are required.

### What can Pika check besides metrics?

Service checks over HTTP and HTTPS, TCP, and ICMP, including detection of certificate expiry. It also keeps an asset inventory, grades risk from critical to low, and records an audit history, with authentication through basic auth with bcrypt, OpenID Connect, or GitHub OAuth.

### How are the Pika server and agent versions handled?

Separately. The server version comes from the git description, and the agent version is generated from the short hash of the last commit that touched the agent package, so a probe and a server deployed separately can be at different versions and both report what they are.

## Sources

- [License: Apache-2.0](https://github.com/pika-monitor/pika/blob/main/LICENSE)
- [pika-monitor/pika on GitHub](https://github.com/pika-monitor/pika)
- [Project website](https://pika.termark.app)
- [README](https://github.com/pika-monitor/pika/blob/main/README.md)
- [Releases](https://github.com/pika-monitor/pika/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pika-monitor-pika
