glance-docker-compose.yml
← Back to explorer
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
title: "Vargo"
pages:
- name: "Vargo Dashboard"
columns:
- size: small
widgets:
- type: calendar
first-day-of-week: monday
- type: clock
timezone: "timezone"
hour-format: 12h
show-seconds: false
show-date: true
- type: markets
markets:
- symbol: BTC
name: Bitcoin
- symbol: ETH
name: Ethereum
- symbol: SOL
name: Solana
- symbol: DOGE
name: DogeCoin
- type: reddit
title: "Reddit"
show-flairs: true
subreddit: name-of-your-subreddit
limit: 5
collapse-after: 3
- size: full
widgets:
- type: docker-containers
containers:
<container-1>:
name: Name 1
description: Desc 1
icon: simple-icons-icon
hide: false
<container-2>:
name: Name 2
url: Url
description: Desc 2
icon: simple-icons-icon
<container-3>:
hide: true
<container-4>:
hide: true
<container-5>:
name: Name 5
url: Url
description: Desc 5
icon: simple-icons-icon
<container-6>:
name: Name 6
url: url
description: Desc 6
icon: simple-icons-icon
<container-7>:
hide: true
<container-8>:
name: Name 8
url: url
description: Desc 8
icon: simple-icons-icon
<container-9>:
name: Name 9
url: url
description: Desc 9
icon: simple-icons-icon
<container-10>:
name: Name 10
url: url
description: Desc 10
icon: simple-icons-icon
<container-11>:
name: Name 11
url: url
description: Desc 11
icon: simple-icons-icon
<container-12>:
hide: true
sort-by: cpu
limit: 8
refresh-interval: 15
- type: monitor
cache: 5m # HTTP check every 5 minutes
title: "Services"
sites:
- title: Service_1
url: site-url
timeout: 12s
icon: simple-icons-icon
- title: Service_2
url: site-url
timeout: 12s
icon: simple-icons-icon
- title: Service_3
url: site-url
timeout: 12s
icon: simple-icons-icon
- title: Service_4
url: site-url
timeout: 12s
icon: simple-icons-icon
- title: Service_5
url: site-url
timeout: 12s
icon: simple-icons-icon
- title: Service_6
url: site-url
timeout: 12s
icon: simple-icons-icon
- title: Service_7
url: site-url
timeout: 12s
icon: simple-icons-icon
- type: server-stats
title: "Server Metrics"
servers:
- type: remote
name: "Vargo"
url: glance-agent-url
timeout: 12s
refresh-interval: 10
- type: custom-api
cache: 1h
title: Internet Speed
title-url: title-url
url: url
headers:
Authorization: Bearer <TOKEN>
Accept: application/json
subrequests:
stats:
url: https://your.speedtest.com/api/v1/stats
headers:
Authorization: Bearer <TOKEN>
Accept: application/json
options:
showPercentageDiff: true
template: |
{{ $showPercentage := .Options.BoolOr "showPercentageDiff" true }}
{{ $stats := .Subrequest "stats" }}
<div class="flex justify-between text-center margin-block-3">
<div>
{{ $downloadChange := percentChange ($stats.JSON.Float "data.download.avg_bits") (.JSON.Float "data.download_bits")
}}
{{ if $showPercentage }}
<div
class="size-small {{ if gt $downloadChange 0.0 }}color-positive{{ else if lt $downloadChange 0.0 }}color-negative{{ else }}color-primary{{ end }}"
style="display: inline-flex; align-items: center;">
{{ $downloadChange | printf "%+.1f%%" }}
{{ if gt $downloadChange 0.0 }}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"
style="height: 1em; margin-left: 0.25em;" class="size-4">
<path fill-rule="evenodd"
d="M9.808 4.057a.75.75 0 0 1 .92-.527l3.116.849a.75.75 0 0 1 .528.915l-.823 3.121a.75.75 0 0 1-1.45-.382l.337-1.281a23.484 23.484 0 0 0-3.609 3.056.75.75 0 0 1-1.07.01L6 8.06l-3.72 3.72a.75. 75 0 1 1-1.06-1.061l4.25-4.25a.75.75 0 0 1 1.06 0l1.756 1.755a25.015 25.015 0 0 1 3.508-2.85l-1.46-.398a.75.75 0 0 1-.526-.92Z"
clip-rule="evenodd" />
</svg>
{{ else if lt $downloadChange 0.0 }}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"
style="height: 1em; margin-left: 0.25em;" class="size-4">
<path fill-rule="evenodd"
d="M1.22 4.22a.75.75 0 0 1 1.06 0L6 7.94l2.761-2.762a.75.75 0 0 1 1.158.12 24.9 24.9 0 0 1 2.718 5.556l.729-1.261a.75.75 0 0 1 1.299.75l-1.591 2.755a.75.75 0 0 1-1.025.275l-2.756-1.591a.75.7 5 0 1 1 .75-1.3l1.097.634a23.417 23.417 0 0 0-1.984-4.211L6.53 9.53a.75.75 0 0 1-1.06 0L1.22 5.28a.75.75 0 0 1 0-1.06Z"
clip-rule="evenodd" />
</svg>
{{ end }}
</div>
{{ end }}
<div class="color-highlight size-h3">{{ .JSON.Float "data.download_bits" | mul 0.000001 | printf "%.1f" }}</div>
<div class="size-h6">DOWNLOAD</div>
</div>
<div>
{{ $uploadChange := percentChange ($stats.JSON.Float "data.upload.avg_bits") (.JSON.Float "data.upload_bits") }}
{{ if $showPercentage }}
<div
class="size-small {{ if gt $uploadChange 0.0 }}color-positive{{ else if lt $uploadChange 0.0 }}color-negative{{ else }}color-primary{{ end }}"
style="display: inline-flex; align-items: center;">
{{ $uploadChange | printf "%+.1f%%" }}
{{ if gt $uploadChange 0.0 }}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"
style="height: 1em; margin-left: 0.25em;" class="size-4">
<path fill-rule="evenodd"
d="M9.808 4.057a.75.75 0 0 1 .92-.527l3.116.849a.75.75 0 0 1 .528.915l-.823 3.121a.75.75 0 0 1-1.45-.382l.337-1.281a23.484 23.484 0 0 0-3.609 3.056.75.75 0 0 1-1.07.01L6 8.06l-3.72 3.72a.75. 75 0 1 1-1.06-1.061l4.25-4.25a.75.75 0 0 1 1.06 0l1.756 1.755a25.015 25.015 0 0 1 3.508-2.85l-1.46-.398a.75.75 0 0 1-.526-.92Z"
clip-rule="evenodd" />
</svg>
{{ else if lt $uploadChange 0.0 }}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"
style="height: 1em; margin-left: 0.25em;" class="size-4">
<path fill-rule="evenodd"
d="M1.22 4.22a.75.75 0 0 1 1.06 0L6 7.94l2.761-2.762a.75.75 0 0 1 1.158.12 24.9 24.9 0 0 1 2.718 5.556l.729-1.261a.75.75 0 0 1 1.299.75l-1.591 2.755a.75.75 0 0 1-1.025.275l-2.756-1.591a.75.7 5 0 1 1 .75-1.3l1.097.634a23.417 23.417 0 0 0-1.984-4.211L6.53 9.53a.75.75 0 0 1-1.06 0L1.22 5.28a.75.75 0 0 1 0-1.06Z"
clip-rule="evenodd" />
</svg>
{{ end }}
</div>
{{ end }}
<div class="color-highlight size-h3">{{ .JSON.Float "data.upload_bits" | mul 0.000001 | printf "%.1f" }}</div>
<div class="size-h6">UPLOAD</div>
</div>
<div>
{{ $pingChange := percentChange ($stats.JSON.Float "data.ping.avg") (.JSON.Float "data.ping") }}
{{ if $showPercentage }}
<div
class="size-small {{ if gt $pingChange 0.0 }}color-negative{{ else if lt $pingChange 0.0 }}color-positive{{ else }}color-primary{{ end }}"
style="display: inline-flex; align-items: center;">
{{ $pingChange | printf "%+.1f%%" }}
{{ if lt $pingChange 0.0 }}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"
style="height: 1em; margin-left: 0.25em;" class="size-4">
<path fill-rule="evenodd"
d="M1.22 4.22a.75.75 0 0 1 1.06 0L6 7.94l2.761-2.762a.75.75 0 0 1 1.158.12 24.9 24.9 0 0 1 2.718 5.556l.729-1.261a.75.75 0 0 1 1.299.75l-1.591 2.755a.75.75 0 0 1-1.025.275l-2.756-1.591a.75.7 5 0 1 1 .75-1.3l1.097.634a23.417 23.417 0 0 0-1.984-4.211L6.53 9.53a.75.75 0 0 1-1.06 0L1.22 5.28a.75.75 0 0 1 0-1.06Z"
clip-rule="evenodd" />
</svg>
{{ else if gt $pingChange 0.0 }}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor"
style="height: 1em; margin-left: 0.25em;" class="size-4">
<path fill-rule="evenodd"
d="M9.808 4.057a.75.75 0 0 1 .92-.527l3.116.849a.75.75 0 0 1 .528.915l-.823 3.121a.75.75 0 0 1-1.45-.382l.337-1.281a23.484 23.484 0 0 0-3.609 3.056.75.75 0 0 1-1.07.01L6 8.06l-3.72 3.72a.75. 75 0 1 1-1.06-1.061l4.25-4.25a.75.75 0 0 1 1.06 0l1.756 1.755a25.015 25.015 0 0 1 3.508-2.85l-1.46-.398a.75.75 0 0 1-.526-.92Z"
clip-rule="evenodd" />
</svg>
{{ end }}
</div>
{{ end }}
<div class="color-highlight size-h3">{{ .JSON.Float "data.ping" | printf "%.0f ms" }}</div>
<div class="size-h6">PING</div>
</div>
</div>
- type: custom-api
title: Nearby Aircraft
cache: 1m
url: "https://opensky-network.org/api/states/all?lamin=min-latitude&lomin=min-longitude&lamax=max-latitutde&lomax=max-longitude"
template: |-
<div class="opensky-aircraft-stats">
{{ $states := .JSON.Array "states" }}
{{ $statesCount := len $states }}
<div class="margin-block-2">
<div class="size-h6">AIRCRAFT NEARBY: {{ $statesCount }}</div>
</div>
{{ if gt $statesCount 0 }}
{{ $plane := index $states 0 }}
{{ $callsign := $plane.String "1" }}
{{ $icao24 := $plane.String "0" }}
{{ $origin := $plane.String "2" }}
{{ $onGround := $plane.Bool "8" }}
{{ $altitude := $plane.Float "7" }}
{{ $speed := $plane.Float "9" }}
<div class="margin-block-2">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
<div>
<div class="color-highlight size-h3">
{{ if ne $callsign "" }}{{ $callsign }}{{ else }}{{ $icao24 }}{{ end }}
</div>
<div class="size-h6">CALLSIGN</div>
</div>
<div>
<div class="color-highlight size-h3 text-truncate" style="max-width: 100%;">
{{ if ne $origin "" }}{{ $origin }}{{ else }}-{{ end }}
</div>
<div class="size-h6">ORIGIN</div>
</div>
</div>
</div>
<div class="margin-block-2">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
<div>
<div class="color-highlight size-h3">
{{ if and (not $onGround) (ne $altitude 0.0) }}{{ printf "%.0f" $altitude }}m{{ else }}-{{ end }}
</div>
<div class="size-h6">ALTITUDE</div>
</div>
<div>
<div class="color-highlight size-h3">
{{ if and (not $onGround) (ne $speed 0.0) }}{{ printf "%.0f" $speed }}m/s{{ else }}-{{ end }}
</div>
<div class="size-h6">SPEED</div>
</div>
</div>
</div>
{{ end }}
</div>
- type: group
layout: horizontal
widgets:
- type: custom-api
title: "F1 • Next Race"
cache: 1h
url: "https://f1api.dev/api/current/next?timezone={TIMEZONE}"
template: |-
{{ $img := "https://cdn-icons-png.flaticon.com/512/668/668087.png" }}
{{ $race := .JSON.String "race.0.raceName" }}
{{ if not $race }}{{ $race = (printf "Round %s" (.JSON.String "round")) }}{{ end }}
{{ $date := .JSON.String "race.0.schedule.race.date" }}
{{ $time := .JSON.String "race.0.schedule.race.time" }}
{{ $cname := .JSON.String "race.0.circuit.circuitName" }}
{{ $city := .JSON.String "race.0.circuit.city" }}
{{ $country := .JSON.String "race.0.circuit.country" }}
<div style="display:grid;grid-template-columns:56px 1fr;gap:12px;align-items:start">
<img src="{{ $img }}" alt="F1" style="width:56px;height:56px;object-fit:contain;opacity:.9;filter:grayscale(1);" />
<div>
<div class="size-h4 color-highlight">{{ $race }}</div>
<div class="size-h6">{{ $cname }}</div>
<div class="size-h6">{{ $city }}, {{ $country }}</div>
<div class="size-h6" style="margin-top:6px">
Race: {{ $date }} {{ if $time }}• {{ $time }}{{ end }}
</div>
<div style="border-top:1px solid;margin-top:10px;padding-top:8px" class="size-h6">
FP1: {{ .JSON.String "race.0.schedule.fp1.date" }} {{ if .JSON.String "race.0.schedule.fp1.time" }}• {{ .JSON.String "race.0.schedule.fp1.time" }}{{ end }}<br/>
Qualy: {{ .JSON.String "race.0.schedule.qualy.date" }} {{ if .JSON.String "race.0.schedule.qualy.time" }}• {{ .JSON.String "race.0.schedule.qualy.time" }}{{ end }}
</div>
</div>
</div>
- type: custom-api
title: "F1 • Last Race Result"
cache: 12h
url: "https://f1api.dev/api/current/last?timezone={TIMEZONE}"
template: |-
{{ $img := "https://cdn-icons-png.flaticon.com/512/668/668087.png" }}
{{ $name := .JSON.String "race.0.raceName" }}
{{ $cname := .JSON.String "race.0.circuit.circuitName" }}
{{ $city := .JSON.String "race.0.circuit.city" }}
{{ $country := .JSON.String "race.0.circuit.country" }}
{{ $date := .JSON.String "race.0.schedule.race.date" }}
{{ $winName := .JSON.String "race.0.winner.name" }}
{{ $winSur := .JSON.String "race.0.winner.surname" }}
{{ $winShort := .JSON.String "race.0.winner.shortName" }}
{{ $team := .JSON.String "race.0.teamWinner.teamName" }}
{{ $laps := .JSON.String "race.0.laps" }}
<div style="display:grid;grid-template-columns:56px 1fr;gap:12px;align-items:start">
<img src="{{ $img }}" alt="Winner" style="width:56px;height:56px;object-fit:contain;opacity:.9;filter:grayscale(1);" />
<div>
<div class="size-h4 color-highlight">{{ $name }}</div>
<div class="size-h6">{{ $cname }}</div>
<div class="size-h6">{{ $city }}, {{ $country }}</div>
<div class="size-h6" style="margin-top:6px">Race: {{ $date }} • Laps: {{ $laps }}</div>
<div style="border-top:1px solid;margin-top:10px;padding-top:8px">
<div class="size-h5 color-positive">Winner</div>
<div class="size-h3">
{{ if $winShort }}{{ $winShort }} · {{ end }}{{ $winName }} {{ $winSur }}
</div>
<div class="size-h6">{{ $team }}</div>
</div>
</div>
</div>
- size: small
widgets:
- type: weather
location: Location
units: metric
hour-format: 12h
- type: custom-api
title: Air Quality
cache: 10m
url: "https://api.waqi.info/feed/geo:coordinates/?token=generate-token-from-site"
template: |-
{{ $aqi := printf "%03s" (.JSON.String "data.aqi") }}
{{ $aqiraw := .JSON.String "data.aqi" }}
{{ $updated := .JSON.String "data.time.iso" }}
{{ $humidity := .JSON.Float "data.iaqi.h.v" }}
{{ $ozone := .JSON.String "data.iaqi.o3.v" }}
{{ $pm25 := .JSON.String "data.iaqi.pm25.v" }}
{{ $pressure := .JSON.Float "data.iaqi.p.v" }}
<div class="flex justify-between">
<div class="size-h5">
{{ if le $aqi "050" }}
<div class="color-positive">Good air quality</div>
{{ else if le $aqi "100" }}
<div class="color-primary">Moderate air quality</div>
{{ else }}
<div class="color-negative">Bad air quality</div>
{{ end }}
</div>
</div>
<div class="color-highlight size-h2">AQI: {{ $aqiraw }}</div>
<div style="border-bottom: 1px solid; margin-block: 10px;"></div>
<div class="margin-block-2">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
<div>
<div class="size-h3 color-highlight">{{ printf "%.1f" $humidity }}%</div>
<div class="size-h6">HUMIDITY</div>
</div>
<div>
<div class="size-h3 color-highlight">{{ $ozone }} μg/m³</div>
<div class="size-h6">OZONE</div>
</div>
<div>
<div class="size-h3 color-highlight">{{ $pm25 }} μg/m³</div>
<div class="size-h6">PM2.5</div>
</div>
<div>
<div class="size-h3 color-highlight">{{ printf "%.1f" $pressure }} hPa</div>
<div class="size-h6">PRESSURE</div>
</div>
</div>
<div class="size-h6" style="margin-top: 10px;">Last Updated at {{ slice $updated 11 16 }}</div>
</div>
- type: custom-api
title: Random Capybara
cache: 10m
url: "https://animals.maxz.dev/api/capybara/random"
template: |-
{{ $img := .JSON.String "image" }}
{{ if $img }}
<img src="{{ $img }}" style="width:100%;height:auto;border-radius:8px;" />
{{ else }}
<div class="color-negative">No image in API response</div>
{{ end }}
- type: releases
show-source-icon: true
token: Github_TOKEN
repositories:
- nextcloud/server
- dani-garcia/vaultwarden
- portainer/portainer
- fastapi/fastapi
limit: 6
refresh-interval: 43200 # 12 hours
- type: to-do
title: "Todo"
items:
- text: "Add more services to Monitor"
done: false
- text: "Tune server-stats agent"
done: false