docs: community polish for public readiness #21
@@ -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
|
||||||
@@ -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
@@ -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,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
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user