mirror of
https://github.com/airlabspl/uptimemonitor.git
synced 2025-08-23 00:16:31 +02:00
Compare commits
6 Commits
v0.0.2-alp
...
v0.1.0-alp
Author | SHA1 | Date | |
---|---|---|---|
![]() |
daf27255d6 | ||
![]() |
f2f24532ed | ||
![]() |
2adbc0b073 | ||
![]() |
50a46d8ad9 | ||
![]() |
17cabd68ad | ||
![]() |
1db65385ce |
45
.github/workflows/docker.yml
vendored
Normal file
45
.github/workflows/docker.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
name: Docker
|
||||||
|
|
||||||
|
on: push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
push_to_registry:
|
||||||
|
name: Push Docker image to Docker Hub
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
packages: write
|
||||||
|
contents: read
|
||||||
|
attestations: write
|
||||||
|
id-token: write
|
||||||
|
steps:
|
||||||
|
- name: Check out the repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Log in to Docker Hub
|
||||||
|
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Extract metadata (tags, labels) for Docker
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
|
||||||
|
with:
|
||||||
|
images: airlabs/uptimemonitor
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
id: push
|
||||||
|
uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ./Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
|
- name: Generate artifact attestation
|
||||||
|
uses: actions/attest-build-provenance@v2
|
||||||
|
with:
|
||||||
|
subject-name: index.docker.io/airlabs/uptimemonitor
|
||||||
|
subject-digest: ${{ steps.push.outputs.digest }}
|
||||||
|
push-to-registry: true
|
24
Dockerfile
Normal file
24
Dockerfile
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
FROM golang:latest AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
|
||||||
|
go build -o uptimemonitor \
|
||||||
|
-ldflags "-X uptimemonitor/pkg/version.Version=$(git describe --tags)" \
|
||||||
|
./cmd/uptimemonitor
|
||||||
|
|
||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apk add --no-cache ca-certificates
|
||||||
|
|
||||||
|
COPY --from=builder /app/uptimemonitor .
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
CMD ["./uptimemonitor"]
|
99
README.md
99
README.md
@@ -1,7 +1,106 @@
|
|||||||
# UPTIME MONITOR
|
# UPTIME MONITOR
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
[](https://github.com/airlabspl/uptimemonitor/actions/workflows/go.yml)
|
[](https://github.com/airlabspl/uptimemonitor/actions/workflows/go.yml)
|
||||||
|
|
||||||
[uptimemonitor.dev](https://uptimemonitor.dev)
|
[uptimemonitor.dev](https://uptimemonitor.dev)
|
||||||
|
|
||||||
© 2025 AIR Labs
|
© 2025 AIR Labs
|
||||||
|
|
||||||
|
## Yet another uptime monitor?
|
||||||
|
|
||||||
|
Yes, but with following constraints:
|
||||||
|
|
||||||
|
- 100% self-hosted
|
||||||
|
- Single binary when build
|
||||||
|
- 0 configuration
|
||||||
|
- Simple functionality without bloat
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Download the latest release to a Linux VPS (check the
|
||||||
|
[Releases page](https://github.com/airlabspl/uptimemonitor/releases)):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wget https://github.com/airlabspl/uptimemonitor/releases/download/v0.0.2-alpha/uptimemonitor
|
||||||
|
chmod +x uptimemonitor
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Run it
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./uptimemonitor -addr=":3000"
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also use provided `Dockerfile` and `docker-compose.yml` for reference to
|
||||||
|
run the app using Docker.
|
||||||
|
|
||||||
|
For example, to run a local copy without https enabled:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
SECURE=false COOLIFY_VOLUME_APP=~/testdata docker-compose up
|
||||||
|
```
|
||||||
|
|
||||||
|
## First run
|
||||||
|
|
||||||
|
When you first run the application you will be asked to create a new account,
|
||||||
|
which you will then use to log in.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
To start monitoring a given url, add the url on a `/new` page. You can specify
|
||||||
|
the HTTP method the check will use (GET, POST, etc.) as well as add custom
|
||||||
|
headers and body to the request.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Incidents
|
||||||
|
|
||||||
|
When the check fails, the incident will be created and will stay open until the
|
||||||
|
upcoming check succeeds. You can dig into the failing request details on a
|
||||||
|
incident page.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Webhooks
|
||||||
|
|
||||||
|
If you want to get notified when an incident happens, you can also configure a
|
||||||
|
webhook notification to a given url of choice (e.g. slack or google chat webhook
|
||||||
|
url). You can use `{{ .Url }}` and `{{ .StatusCode }}` variables inside a body
|
||||||
|
to pass those information to the webhook.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Https
|
||||||
|
|
||||||
|
Because the app uses secure cookies for authentication, it is required to use
|
||||||
|
some reverse proxy with https certificate configured.
|
||||||
|
|
||||||
|
If you want to test the app without secure cookies enabled, provide the
|
||||||
|
`-secure=false` flag.
|
||||||
|
|
||||||
|
## Backups
|
||||||
|
|
||||||
|
This app uses a sqlite database so to backup the data just copy the
|
||||||
|
`uptimemonitor.sqlite*` files to a new location.
|
||||||
|
|
||||||
|
## Pricing
|
||||||
|
|
||||||
|
The app is free to use but if you are using it commercially and can aford a
|
||||||
|
small donation- please use Github Sponsors.
|
||||||
|
|
||||||
|
The donations of $50 a month and above will be featured in a sponsors area
|
||||||
|
inside the application dashboard.
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
- Monitor status badges
|
||||||
|
- Change password
|
||||||
|
- Manage users
|
||||||
|
- Timezones
|
||||||
|
- Reset password via cli
|
||||||
|
- Add "Test Webhook" button with fake incident
|
||||||
|
- Sort monitors option (with localstorage sync) by created_at/name(domain)
|
||||||
|
29
TODO.md
29
TODO.md
@@ -1,29 +0,0 @@
|
|||||||
# TODO
|
|
||||||
|
|
||||||
What's left to do:
|
|
||||||
|
|
||||||
- [ ] Get app version from git tag
|
|
||||||
- [ ] Add documentation
|
|
||||||
- [ ] Document how to install
|
|
||||||
- [ ] Document webhook parsing and available variables
|
|
||||||
- [ ] Release 🎉
|
|
||||||
|
|
||||||
Optional:
|
|
||||||
|
|
||||||
- [ ] Monitor status
|
|
||||||
- [ ] Change password
|
|
||||||
- [ ] Add users
|
|
||||||
- [ ] Remove users
|
|
||||||
- [ ] Change user passwords
|
|
||||||
- [ ] Timezones
|
|
||||||
- [ ] Reset password via cli
|
|
||||||
- [ ] Use the same form for creation and editing of monitor
|
|
||||||
- [ ] Save check response
|
|
||||||
- [ ] Add check response modal (div#modals + append when clicked + destroy when
|
|
||||||
clicked)
|
|
||||||
- [ ] Mobile breadcrumbs (dropdown/select)
|
|
||||||
- [ ] Add "Test Webhook" button with fake incident
|
|
||||||
- [ ] Sort monitors option (with localstorage sync) by created_at/name(domain)
|
|
||||||
- [ ] Session expiration
|
|
||||||
- [ ] Test check timeout
|
|
||||||
- [ ] Loading placeholders (skeletons)
|
|
@@ -23,12 +23,16 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.StringVar(&dsn, "dsn", "uptimemonitor.sqlite?_journal_mode=WAL&_busy_timeout=5000&_synchronous=FULL&_txlock=immediate", "database server name")
|
flag.StringVar(&dsn, "dsn", "data/uptimemonitor.sqlite?_journal_mode=WAL&_busy_timeout=5000&_synchronous=FULL&_txlock=immediate", "database server name")
|
||||||
flag.StringVar(&addr, "addr", ":3000", "server address")
|
flag.StringVar(&addr, "addr", ":3000", "server address")
|
||||||
flag.BoolVar(&secure, "secure", true, "use https")
|
flag.BoolVar(&secure, "secure", true, "use https")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
if os.Getenv("SECURE") == "false" {
|
||||||
|
secure = false
|
||||||
|
}
|
||||||
|
|
||||||
store := store.New(dsn)
|
store := store.New(dsn)
|
||||||
service := service.New(store)
|
service := service.New(store)
|
||||||
handler := handler.New(store, service, secure)
|
handler := handler.New(store, service, secure)
|
||||||
|
2
data/.gitignore
vendored
Normal file
2
data/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
15
docker-compose.yml
Normal file
15
docker-compose.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# documentation: https://github.com/airlabspl/uptimemonitor/blob/master/README.md
|
||||||
|
# slogan: A self-hosted, simple web uptime monitor
|
||||||
|
# tags: uptime,downtime,monitor,self-hosted
|
||||||
|
# logo: svgs/uptime-monitor-dev.svg
|
||||||
|
# port: 3000
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: airlabs/uptimemonitor:master
|
||||||
|
environment:
|
||||||
|
- SECURE=${SECURE}
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ${COOLIFY_VOLUME_APP}:/app/data
|
BIN
docs/incident.png
Normal file
BIN
docs/incident.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 86 KiB |
BIN
docs/new.png
Normal file
BIN
docs/new.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 72 KiB |
BIN
docs/setup.png
Normal file
BIN
docs/setup.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
BIN
docs/uptimemonitor.png
Normal file
BIN
docs/uptimemonitor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 75 KiB |
BIN
docs/webhook.png
Normal file
BIN
docs/webhook.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
@@ -39,20 +39,15 @@
|
|||||||
<footer class="text-sm text-base-content p-4 flex flex-col md:flex-row gap-12 md:gap-4">
|
<footer class="text-sm text-base-content p-4 flex flex-col md:flex-row gap-12 md:gap-4">
|
||||||
<nav class="flex flex-col gap-2 flex-1">
|
<nav class="flex flex-col gap-2 flex-1">
|
||||||
<h6 class="footer-title truncate">{{ .User.Name }}</h6>
|
<h6 class="footer-title truncate">{{ .User.Name }}</h6>
|
||||||
<a class="link link-hover">Account settings</a>
|
|
||||||
<a class="link link-hover">Manage users</a>
|
|
||||||
<a class="link link-hover" href="/logout">Log out</a>
|
<a class="link link-hover" href="/logout">Log out</a>
|
||||||
</nav>
|
</nav>
|
||||||
<nav class="flex flex-col gap-2 flex-1">
|
<nav class="flex flex-col gap-2 flex-1">
|
||||||
<h6 class="footer-title">UPTIMEMONITOR</h6>
|
<h6 class="footer-title">UPTIMEMONITOR</h6>
|
||||||
<a class="link link-hover">Documentation</a>
|
<a class="link link-hover" href="https://github.com/airlabspl/uptimemonitor/blob/master/README.md"
|
||||||
<a class="link link-hover">Pricing</a>
|
target="_blank" rel="noopener noreferrer">Documentation</a>
|
||||||
<a class="link link-hover">Terms of use</a>
|
|
||||||
</nav>
|
</nav>
|
||||||
<nav class="flex flex-col gap-2 flex-1">
|
<nav class="flex flex-col gap-2 flex-1">
|
||||||
<h6 class="footer-title">AIR Labs</h6>
|
<h6 class="footer-title">AIR Labs</h6>
|
||||||
<a class="link link-hover">About us</a>
|
|
||||||
<a class="link link-hover">Other products</a>
|
|
||||||
<a class="link link-hover flex items-center gap-1" href="https://x.com/airlabspl" target="_blank">
|
<a class="link link-hover flex items-center gap-1" href="https://x.com/airlabspl" target="_blank">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300" version="1.1" class="size-[11px]!">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300" version="1.1" class="size-[11px]!">
|
||||||
<path
|
<path
|
||||||
|
Reference in New Issue
Block a user