Basically, every now and then, YOU send a ping (really just an HTTP request) to the LifePing server.
The server then stores the associated request timestamp in a simple text file.
Whenever someone visits the hosted web page, they can see how long ago the last ping was.
It also includes the times for the last 10 pings and that's it.
Depending on how much time has passed since the latest ping, it will display a different status message:
| Status | Meaning |
|---|---|
| โซ grey | no ping recorded yet |
| ๐ข green | last ping younger than LIFEPING_YELLOW_AFTER |
| ๐ก amber | older than that, but younger than LIFEPING_RED_AFTER |
| ๐ด red | no sign of life for longer than LIFEPING_RED_AFTER |
mkdir -p secrets
openssl rand -hex 32 > secrets/lifeping_tokenEdit the lines marked # CHANGE ME in compose.yaml then run:
docker compose up --build -dThe container runs as the distroless nonroot user (UID/GID 65532). The
named volume in compose.yaml works as is. If you bind-mount a host directory
to /data instead, make it writable by that user:
sudo chown 65532:65532 ./dataPings are stored in /data/pings.log, one UTC timestamp per line.
| Variable | Default | Description |
|---|---|---|
LIFEPING_TOKEN |
โ | Bearer token for POST /api/ping |
LIFEPING_TOKEN_FILE |
โ | File containing the token (for Docker secrets). Set exactly one of the two token variables. |
LIFEPING_YELLOW_AFTER |
12h |
Age after which the status turns amber (90m, 12h, 1d 6h, โฆ) |
LIFEPING_RED_AFTER |
24h |
Age after which the status turns red; must be greater than the amber threshold |
LIFEPING_HISTORY |
10 |
How many recent pings the page shows (1โ1000) |
LIFEPING_DATA_DIR |
/data |
Directory holding pings.log |
LIFEPING_BIND |
0.0.0.0:8080 |
Listen address |
LIFEPING_TITLE |
Life Ping |
Site title shown in the header and browser tab (max 100 characters) |
LIFEPING_STRINGS_FILE |
โ | JSON file overriding UI strings, see Customising the text |
RUST_LOG |
lifeping=info |
Log filter |
You can use a custom page title by setting LIFEPING_TITLE.
Every other piece of text on the page can be changed by pointing LIFEPING_STRINGS_FILE at a JSON file with the
same structure as web/strings.json.
You only need to list the strings you want to change; the rest keep their defaults:
{
"en": { "headline.green": "Still kicking!" },
"fr": { "headline.green": "Toujours lร !" }
}{hours} and {relative} placeholders are dynamically replaced on page load with their real values.
If using custom text translations with Docker, you will need to make sure the file is mounted into the container, e.g. ./strings.json:/config/strings.json:ro,
and set LIFEPING_STRINGS_FILE: /config/strings.json.
Sending a ping is a simple as sending an HTTP POST request to the server:
curl --request POST --header "Authorization: Bearer $TOKEN" https://lifeping.example.com/api/ping
# {"timestamp":"2026-09-27T09:30:00Z"}This makes it easy to implement a ping send in pretty much any device you own.
There is already a default bash script provided in scripts/lifeping-ping.
The script expects the LIFEPING_URL env var to be set and it will read the ping token from ~/.config/lifeping/token. Feel free to adapt it to your specific needs.
When ran, it will attempt to send a single ping to the server and notify you via notify-send.
To easily install the script:
install -D --mode=755 scripts/lifeping-ping ~/.local/bin/lifeping-ping
install -D --mode=600 secrets/lifeping_token ~/.config/lifeping/tokenSince I use Hyprland, I have configured a keybind in my hyprland.lua to make it easy to send a ping:
hl.bind(
mainMod .. " + P",
hl.dsp.exec_cmd("bash ~/.local/bin/lifeping-ping"),
{ description = "Send a ping to the LifePing server" }
)There is an open-source Android app called HTTP Shortcuts that you can use to easily create shortcuts/widgets that trigger an HTTP request.
Once installed, you can configure the app to work with LifePing:
- Create a new Regular HTTP Shortcut, named e.g. "I'm alive".
- Basic request settings: method
POST, URLhttps://lifeping.example.com/api/ping. - Request headers: add
Authorizationwith valueBearer <your token>. - Response handling: show a toast on success and on failure.
- Save, then long-press the shortcut โ Place on home screen, or add an HTTP Shortcuts widget. One tap now sends a ping.
| Endpoint | Auth | Description |
|---|---|---|
GET /api/status |
none | Current status, latest ping, recent history, thresholds |
POST /api/ping |
Bearer |
Records a ping at server time, returns {"timestamp": โฆ} |
GET /healthz |
none | Returns ok |
To get latest pings:
curl https://{lifeping.example.com}/api/status{
"now": "2026-09-27T09:30:00Z",
"status": "green",
"latest": "2026-09-27T07:58:02Z",
"history": ["2026-09-27T07:58:02Z", "2026-09-26T19:03:10Z"],
"total_pings": 2,
"thresholds": { "yellow_after_secs": 43200, "red_after_secs": 86400 }
}LIFEPING_TOKEN=dev LIFEPING_DATA_DIR=./data LIFEPING_BIND=127.0.0.1:8080 cargo run
cargo test
cargo clippy --all-targets -- --deny warnings
cargo fmt --checkTo watch the colours change without waiting a day, start the server with
LIFEPING_YELLOW_AFTER=1m LIFEPING_RED_AFTER=2m.
