Login: add an in-memory per-IP throttle (8 failed attempts -> 15-min lockout, 429 + Retry-After), raise the change-password minimum to 8 with a 72-char cap, and apply the same minimum on the StartOS Set Login Password action. Records: add a record_floor column for manually-pinned bests plus recomputeRecord(); the live record is now the direction-aware best of the best logged value and the floor, recomputed on entry edit/delete so it can drop again (never below the floor). Settings exposes the floor as an override and shows the live best as a placeholder. Bump package 0.1.6:0 -> 0.1.7:0 and the service-worker cache to v7.
Premier Gunner on StartOS
Upstream repo: https://github.com/ten31/premier-gunner
Premier Gunner is a kid-friendly, mobile-friendly soccer training tracker for a single player. It logs daily training across categories, plans future sessions, tracks goals, and shows progress toward a big reward. This repository packages the app as a StartOS .s9pk service for StartOS 0.4.0.x.
Getting Started
This package builds its own Docker image from the vendored Node app (it does not pull a prebuilt image from a registry). The build copies the app source into ./app and installs/compiles its dependencies inside the image.
npm ci # install the start-sdk packaging deps
make # vendor the app, build images, and pack the .s9pk(s)
To learn the general workflow, see the StartOS Packaging Guide.
Table of Contents
- Image and Container Runtime
- Volume and Data Layout
- Installation and First-Run Flow
- Configuration Management
- Network Access and Interfaces
- Actions (StartOS UI)
- Backups and Restore
- Health Checks
- Dependencies
- Build Layout
- Quick Reference for AI Consumers
Image and Container Runtime
| Property | Value |
|---|---|
| Image | Built locally from ./Dockerfile (Node 22) |
| Architectures | x86_64, aarch64 |
| Command | node src/server.js (cwd /app) |
Volume and Data Layout
| Volume | Mount Point | Purpose |
|---|---|---|
main |
/data |
SQLite database, sessions, and store.json (login password) |
The app reads PG_DATA_DIR=/data and writes its SQLite DB there. The package's store.json (managed by StartOS) lives in the same volume and holds the login password.
Installation and First-Run Flow
- On install, a 16-character random login password is generated and written to
store.json. - On every start,
mainreads the password fromstore.jsonand injects it asPG_PASSWORD. The app treats this env var as authoritative and (re)hashes it, so the login password always matches what StartOS holds. - The user opens the ui interface, logs in, and (recommended) sets their own password via the Set Login Password action.
Configuration Management
The only user-managed setting is the login password, handled by the Set Login Password action — not a config form. The action writes to store.json; the resulting change triggers a daemon restart (via a reactive .const read) so the new password takes effect immediately.
StartOS-managed environment variables injected into the app:
| Variable | Value | Source |
|---|---|---|
NODE_ENV |
production |
static (enables Secure cookie) |
PG_HOST |
0.0.0.0 |
static |
PG_PORT |
3000 |
utils.uiPort |
PG_DATA_DIR |
/data |
main volume mount |
PG_PASSWORD |
(random/user) | store.json → reactive read |
Network Access and Interfaces
| Interface | Port | Protocol | Purpose |
|---|---|---|---|
ui |
3000 | HTTP | Premier Gunner web app |
Access methods: LAN IP, <hostname>.local, Tor .onion, and custom clearnet domains.
Clearnet via StartTunnel
The app serves plain HTTP; StartOS/StartTunnel terminate TLS. Point a StartTunnel domain at the ui interface (see the StartTunnel docs). Because NODE_ENV=production sets the session cookie's Secure flag, the app must be reached over HTTPS — which StartTunnel provides.
Actions (StartOS UI)
| Action | Input | Effect |
|---|---|---|
| Set Login Password | Password (≥4 chars) | Writes the password to store.json; service restarts; sessions cleared |
Backups and Restore
Included in backup: the main volume (database + store.json). Restored fully before the service starts.
Health Checks
| Check | Method | Messages |
|---|---|---|
| Web Interface | Port listening (3000) | Success: "The web interface is ready" / Error: "The web interface is not ready" |
Dependencies
None.
Build Layout
Dockerfile— multi-stage Node 22 build; compilesbetter-sqlite3, copies the app, runsnode src/server.js.Makefile—prepvendors the app from the parent repo into./app(excludingnode_modules/data), then delegates tos9pk.mkto build both arches.startos/— the start-sdk package definition (manifest, main, interfaces, actions, fileModels/store, versions, i18n)../app— generated, git-ignored vendor copy of the Node app used as the Docker build context.
Quick Reference for AI Consumers
package_id: premier-gunner
image: built locally from ./Dockerfile (node:22-bookworm-slim)
architectures: [x86_64, aarch64]
volumes:
main: /data
ports:
ui: 3000
dependencies: none
startos_managed_env_vars:
PG_PASSWORD: from store.json (login password, authoritative)
PG_PORT: 3000
PG_DATA_DIR: /data
PG_HOST: 0.0.0.0
NODE_ENV: production
actions:
- set-password (Set Login Password)