docs: community polish for public readiness #21

Merged
lerko merged 6 commits from chore/community-polish into main 2026-05-24 19:40:01 +00:00
7 changed files with 141 additions and 2 deletions
+46
View File
@@ -0,0 +1,46 @@
# Changelog
## [2026.05.2] — 2026-05-23
### Added
- Comprehensive test suite (94 tests across monitor, server, cluster)
- golangci-lint config with CI enforcement
- Gitea Actions CI pipeline (test + lint)
- Graceful shutdown for HTTP and SSH servers
- Context-aware alert delivery with timeout
- Request size limits on all POST endpoints
- Constant-time secret comparison
- Check interval jitter to prevent thundering herd
- `--version` flag with build metadata injection
### Fixed
- Silent JSON unmarshal failures in alert settings
- Panic on crypto/rand failure replaced with error return
- Alert delivery errors now logged instead of swallowed
- log.Fatalf in goroutines replaced with log.Printf
- Deprecated LineUp/LineDown API calls
### Security
- Cluster secret compared with crypto/subtle (timing-safe)
- http.MaxBytesReader on all JSON endpoints
- ReadHeaderTimeout added to HTTP server
## [2026.05.1] — 2026-05-14
### Added
- Distributed probing with leader + probe nodes
- Config-as-code (YAML apply/export with dry-run, prune)
- TUI visual polish (zebra striping, sparklines, breadcrumbs)
- Incident management and maintenance windows
- 9 alert providers (Discord, Slack, Email, Ntfy, Telegram, PagerDuty, Pushover, Gotify, Webhook)
## [2026.04.1] — Initial independent fork
### Added
- SSH-accessible TUI (Bubble Tea + Wish)
- 6 check types (HTTP, Push, Ping, Port, DNS, Group)
- SQLite and PostgreSQL support
- HA clustering with automatic failover
- Prometheus metrics endpoint
- Public status page
- Uptime Kuma import
+23
View File
@@ -0,0 +1,23 @@
# Contributing
## Development
```sh
go run cmd/goupkeep/main.go -demo # starts with sample data
ssh -p 23234 localhost # connect to TUI
```
## Tests
```sh
go test ./... # unit tests
go test -race ./... # race detector
golangci-lint run ./... # linting
```
## Pull Requests
- Branch from `main`, PR back to `main`
- Conventional Commits for messages (`feat:`, `fix:`, `chore:`)
- Tests must pass, linter must be clean
- One logical change per PR
+4 -1
View File
@@ -6,7 +6,10 @@ COPY go.mod go.sum ./
RUN go mod download RUN go mod download
COPY . . COPY . .
ENV CGO_ENABLED=1 ENV CGO_ENABLED=1
RUN go build -ldflags="-s -w" -o go-upkeep ./cmd/goupkeep/main.go ARG VERSION=dev
ARG COMMIT=none
ARG BUILD_DATE=unknown
RUN go build -ldflags="-s -w -X main.version=${VERSION} -X main.commit=${COMMIT} -X main.date=${BUILD_DATE}" -o go-upkeep ./cmd/goupkeep/main.go
# --- Stage 2: Runner --- # --- Stage 2: Runner ---
FROM alpine:latest FROM alpine:latest
+1
View File
@@ -1,6 +1,7 @@
MIT License MIT License
Copyright (c) 2026 Roman Dvořák Copyright (c) 2026 Roman Dvořák
Copyright (c) 2026 Tyler Koenig
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
+31 -1
View File
@@ -2,7 +2,7 @@
Self-hosted uptime monitor with a TUI you can access over SSH. No browser, no install on the client — just `ssh -p 23234 your-server`. Self-hosted uptime monitor with a TUI you can access over SSH. No browser, no install on the client — just `ssh -p 23234 your-server`.
Originally forked from [RDGames/go-upkeep](https://github.com/RDGames/go-upkeep). This is an independent fork with significant additions. Built on the foundation of [RDGames/go-upkeep](https://github.com/RDGames/go-upkeep).
## What it does ## What it does
@@ -28,6 +28,25 @@ Seed some demo data to see it in action:
go run cmd/goupkeep/main.go -demo go run cmd/goupkeep/main.go -demo
``` ```
## Install
### From source
```bash
go install gitea.lerkolabs.com/lerko/uptime/cmd/goupkeep@latest
```
### Docker
```bash
docker pull lerko/go-upkeep:latest
docker run -p 23234:23234 -p 8080:8080 -v ./data:/data lerko/go-upkeep
```
### Binary
Download from [Releases](https://gitea.lerkolabs.com/lerko/uptime/releases).
## Config as code ## Config as code
Export your current monitors: Export your current monitors:
@@ -85,6 +104,17 @@ First run: attach to the container (`docker attach go-upkeep`), go to the Users
| `UPKEEP_CLUSTER_SECRET` | | Shared key for cluster + API auth | | `UPKEEP_CLUSTER_SECRET` | | Shared key for cluster + API auth |
| `UPKEEP_INSECURE_SKIP_VERIFY` | `false` | Skip TLS verification for checks | | `UPKEEP_INSECURE_SKIP_VERIFY` | `false` | Skip TLS verification for checks |
## Migrating from Uptime Kuma
Export your Kuma backup JSON, then:
```bash
curl -X POST http://localhost:8080/api/import/kuma \
-H "X-Upkeep-Secret: your-secret" \
-H "Content-Type: application/json" \
-d @kuma-backup.json
```
## License ## License
MIT — see [LICENSE](LICENSE). MIT — see [LICENSE](LICENSE).
+19
View File
@@ -0,0 +1,19 @@
# Security Policy
## Reporting a Vulnerability
If you find a security issue, please email security@lerkolabs.com rather than opening a public issue.
Include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
We'll acknowledge within 48 hours and aim to patch within 7 days for critical issues.
## Scope
- SSH server authentication
- Cluster API authentication
- Stored credentials (alert provider tokens)
- Status page information leakage
+17
View File
@@ -27,6 +27,12 @@ import (
"github.com/mattn/go-isatty" "github.com/mattn/go-isatty"
) )
var (
version = "dev"
commit = "none"
date = "unknown"
)
func main() { func main() {
log.SetOutput(os.Stderr) log.SetOutput(os.Stderr)
@@ -38,11 +44,22 @@ func main() {
case "export": case "export":
runExport(os.Args[2:]) runExport(os.Args[2:])
return return
case "version", "--version", "-v":
printVersion()
return
} }
} }
runServe(os.Args[1:]) runServe(os.Args[1:])
} }
func printVersion() {
if version == "dev" {
fmt.Println("go-upkeep dev")
} else {
fmt.Printf("go-upkeep %s (%s, %s)\n", version, commit, date)
}
}
func envOrDefault(key, fallback string) string { func envOrDefault(key, fallback string) string {
if v := os.Getenv(key); v != "" { if v := os.Getenv(key); v != "" {
return v return v