Lunalytics and the three places it points at a license without naming one
🚀 Open source monitoring tool built with Node.js
At a glance
- What is it?
- A Node.js and React self-hosted monitoring tool with multi-user support, nine notification channels and nine SSO providers. Three files point at a license, no file names it, and the build script asks Vite for a config filename the repository does not contain.
- Who is it for?
- Worth reading the source before you depend on it. The license is the first thing to settle: three files send you to a LICENSE file that none of them names, and the manifest field is a placeholder string.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 63 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 3, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Three files point at the license and none of them names it
The license question has three answers in this repository and all three are the same non-answer. The manifest field reads `SEE LICENSE IN LICENSE`, which is a placeholder string rather than an SPDX identifier. The readme closes by saying to see the LICENSE file for licensing information. And the metadata for the repository comes back with no recognized license at all.
What is on disk is a single `LICENSE` file at the root, listed in the repository contents next to the Dockerfile and the readme. So the terms are presumably written down somewhere, but nothing in the three places a tool would look for them tells you what they are. Anything that gates on a license field, a license classifier, or an automated check will see a string that says to go read another file. Worth opening that file before you build a dependency graph around the project.
The build script names a Vite config the repository does not have
The manifest is worth reading for its script names alone, because several of them point somewhere unexpected. `build` is `vite build --config ./vite.config.js`. The repository contents list `vite.config.ts` and no file with a `.js` extension by that name.
That is the kind of mismatch that either resolves through a file generated during setup, or it does not resolve at all, and the readme does not say which. The same script runs in the container build, so a Dockerfile build inherits the question. The root also carries `babel.config.json`, `tsconfig.json` and `vitest.config.mjs` alongside `vite.config.ts`, so there are three separate tool configs in one directory and the build script names a fourth. The `unused` script, `npx unimported`, paired with a `.unimportedrc.json`, suggests the author already watches for drift of a different kind.
The container runs setup on every start
The final Dockerfile stage copies four directories out of the builder, `dist`, `scripts`, `server` and `shared`, takes `node_modules` from a separate native stage, sets two environment variables, exposes one port and then hands control to a script that is not a server start.
FROM node:22.17.0-alpine AS production
ENV NODE_ENV=production \
HUSKY=0
EXPOSE 2308
CMD ["npm", "run", "docker"]That command resolves to `node ./scripts/setup.js && npm run start`, so every container start runs setup before the server. The same setup file is also what `npm run setup` runs, next to `npm install` and a build, which is the path a from-source install takes. Setting `HUSKY=0` exists so the husky prepare hook does not run during the image build, and `npm rebuild better-sqlite3` in the native stage is why the base image installs python3, make and g++.
The docs hand out an https localhost URL with no certificate step
Two installation routes are given, and they differ in more than format. The single container run publishes 2308 and mounts two host directories onto `/app/data` and `/app/logs`. The compose file publishes the same port, adds `container_name: lunalytics`, and prefixes both volume sources with `./`, so a relative path rather than an absolute one. Both use the `latest` tag, so neither pins a release.
The line that follows the setup commands says the application will be accessible on `https://localhost:2308`. No certificate is generated, no TLS variable is set, and the Dockerfile exposes the port plainly with no cert mount. The port number is consistent everywhere it appears, including the health of the compose mapping. The scheme is the only part of that sentence that has nothing behind it.
Node 22 is pinned in three places at three different precisions
The requirements list asks for Node v22.14.0 or higher, and names npm or Yarn plus Git as the other prerequisites. The manifest declares `engines` as node `>= 22.x`, which is coarser than the readme because it does not name a minor. The container pins a third answer: the Dockerfile builds on `node:22.17.0-alpine`, an exact patch on Alpine, and every stage derives from that same base.
A `.nvmrc` file sits in the root as well, so four files are involved in the runtime version. The practical gap is between the readme and the manifest: a Node 22.0 install satisfies the engines field and fails the stated requirement. The `dev` and `watch` scripts add a second port to think about, since the vite dev server runs on port 3000 while the application itself serves on 2308.
The beta warning sits next to a release line that stopped in May
The getting started section opens with a caution block saying the project is under active development and still in beta, and that things may break. It is the first thing a reader sees after the heading, and it is the project's own assessment of itself.
The release history is a slower picture. Three versions are published, all on the same 0.10 line: 0.10.21 in January 2026 described as fixes for various reported bugs, 0.10.22 in March 2026 updating a regex for a discord URL and fixing automatic something, and 0.10.23 in May 2026 fixing various bugs with status pages and session tokens. The manifest version is 0.10.23, so the tree and the newest tag agree. The last push to the default branch is dated 1 August 2026.
Uptime Kuma is the named comparison and sharing is the pitch
The backstory picks a rival by name. The author likes uptime-kuma and gives one reason for building something else: sharing access with friends and colleagues. For the tools that do allow sharing, the complaint is either an interface dating from the 90s or a price the author cannot justify.
So multi-user support is the differentiator rather than a checkbox, and the rest of the feature list follows from it: incident management, role based access control, custom status and dashboard pages, per-user API keys, and single sign on across nine named providers including Authentik, Authelia, Keycloak, Discord, Google, GitHub, Slack and Twitch. Notifications cover Apprise, Discord, email over SMTP, Home Assistant, Pushover, Slack, Telegram and a webhook. Six check types are listed: HTTP(s), TCP, PING, JSON Query, PUSH and Docker containers.
Editorial conclusion
Worth reading the source before you depend on it. The license is the first thing to settle: three files send you to a LICENSE file that none of them names, and the manifest field is a placeholder string. The second is the build, since the build script asks Vite for a config filename that is not in the repository, which is the kind of detail that only shows up on a clean checkout. Beyond that the project is unusually honest about itself, with a beta warning in its own getting started section, a release line that stopped in May 2026, and a roadmap that keeps unchecked boxes with completed sub items under them. Check the LICENSE file yourself and confirm the build works on your Node version before you put it behind anything.
Frequently asked questions
How do you install Lunalytics with Docker?
Two ways are given. A single container run with `docker run -d -p 2308:2308` plus two volume mounts for /app/data and /app/logs, or a compose file using the same image and port with `container_name` set to lunalytics. Both reference the latest tag rather than a pinned release, so the version you get is whatever was pushed most recently.
What Node version does Lunalytics require?
The requirements section asks for Node v22.14.0 or higher, the manifest declares engines as node >= 22.x, and the Dockerfile builds on node:22.17.0-alpine. A .nvmrc file is present in the repository root as well, so the version is pinned in more than one place at more than one precision.
Is Lunalytics still in beta?
The project says so itself. The getting started section opens with a caution block describing it as under active development and still in beta, with the warning that things may break. The newest release is 0.10.23, published on 2026-05-05, and the last push to the default branch is dated 2026-08-01.
What can Lunalytics monitor and who can use it?
Six check types are listed: HTTP(s), TCP, PING, JSON Query, PUSH and Docker containers. It also supports multiple users, incident management, role based access control, custom status and dashboard pages, single sign on through nine providers including Authentik, Authelia, Keycloak, Discord, Google, GitHub, Slack and Twitch, and notifications through eight channels including Apprise, email over SMTP, Home Assistant, Pushover and a webhook.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ksjaay-lunalytics)