# Customizações Duplicati

# Duplicati Monitor

Link: [https://github.com/RafaMunoz/duplicati-monitor](https://github.com/RafaMunoz/duplicati-monitor) git clone [https://github.com/RafaMunoz/duplicati-monitor.git](https://github.com/RafaMunoz/duplicati-monitor.git)

# Duplicati Monitor

<div class="markdown-heading" dir="auto" id="bkmrk-">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/RafaMunoz/duplicati-monitor#duplicati-monitor)</div>Duplicati Monitor is a docker-packaged monitoring solution for Duplicati.

It allows you to control the status of your backups and statistics for each report and notifies you by any means supported by **Apprice**. It is meant to be self-hosted and powered by docker.

## Quick Start

<div class="markdown-heading" dir="auto" id="bkmrk--2">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/RafaMunoz/duplicati-monitor#quick-start)</div>### Notifications

<div class="markdown-heading" dir="auto" id="bkmrk--4">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/RafaMunoz/duplicati-monitor#notifications)</div>To send notifications and satisfy the end user, it has been implemented with the Apprise library, which allows you to send a notification to almost all the most popular notification services available today, such as: Telegram, Discord, Slack, Amazon SNS, Gotify, etc.

You can check all the services available in the [official documentation](https://github.com/caronc/apprise#productivity-based-notifications).

### Templates

<div class="markdown-heading" dir="auto" id="bkmrk--6">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/RafaMunoz/duplicati-monitor#templates)</div>You can create your own templates to receive the information you exactly need.

By default we use the following two:

```
# Succes backup
💾 🟢 <Extra.backup-name>

# Error backup 
💾 🔴 <Extra.backup-name>

```

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" id="bkmrk--8"><div class="zeroclipboard-container">  
</div></div>You can create your own templates in a simple way. You only have to use the symbols `<` and `>` delimit the fields and separating keys with dots `.` to send along with the message that you want.

In the [docs/examples\_report](https://github.com/RafaMunoz/duplicati-monitor/blob/main/docs/examples_report) folder of this repository you have two examples of the JSON reports that Duplicati sends and in which you can see the fields that compose it.

For example, with the following template, the result shown in the telegram image would be obtained.

```
💾 🟢 Backup: <Extra.backup-name>\n - Examined Files: <Data.ExaminedFiles>\n - Duration: <Data.Duration>\n - Status: *<Data.TestResults.ParsedResult>*

```

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" id="bkmrk--9"><div class="zeroclipboard-container">  
</div></div>[![telegram-example-notication](https://github.com/RafaMunoz/duplicati-monitor/raw/main/docs/img/telegram-example-notication.png)](https://github.com/RafaMunoz/duplicati-monitor/blob/main/docs/img/telegram-example-notication.png)

### Environment Variables

<div class="markdown-heading" dir="auto" id="bkmrk--11">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/RafaMunoz/duplicati-monitor#environment-variables)</div><table id="bkmrk-environment-variable-1" style="width: 100%;"><thead><tr><th style="width: 17.998%;">ENVIRONMENT VARIABLE</th><th style="width: 9.6518%;">TYPE</th><th style="width: 18.1199%;">DEFAULT</th><th style="width: 54.2323%;">DESCRIPTION</th></tr></thead><tbody><tr><td style="width: 17.998%;">`URI_NOTIFICATION`</td><td style="width: 9.6518%;">required</td><td style="width: 18.1199%;"> </td><td style="width: 54.2323%;">URI in Apprise format where the notifications will be sent.</td></tr><tr><td style="width: 17.998%;">`TEMPLATE_SUCCESS`</td><td style="width: 9.6518%;">opcional</td><td style="width: 18.1199%;">💾 🟢 &lt;Extra.backup-name&gt;</td><td style="width: 54.2323%;">Message template to be sent when the backup is successful.</td></tr><tr><td style="width: 17.998%;">`TEMPLATE_ERROR`</td><td style="width: 9.6518%;">opcional</td><td style="width: 18.1199%;">💾 🔴 &lt;Extra.backup-name&gt;</td><td style="width: 54.2323%;">Message template that will be sent when the backup is executed in an erroneous way.</td></tr><tr><td style="width: 17.998%;">`PORT`</td><td style="width: 9.6518%;">opcional</td><td style="width: 18.1199%;">8000</td><td style="width: 54.2323%;">Listening port on which the service is set up to receive the reports.</td></tr></tbody></table>

### Docker Run

<div class="markdown-heading" dir="auto" id="bkmrk--13">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/RafaMunoz/duplicati-monitor#docker-run)</div>To start the container you can do it with the following command.

```
docker run -d --name=duplicati-monitor -p 8000:8000 -e URI_NOTIFICATION=tgram://<TOKEN_TELEGRAM_BOT>/<CHANEL_ID>/?format=markdown rafa93m/duplicati-monitor

```

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" id="bkmrk--15"><div class="zeroclipboard-container">  
</div></div>Or you can also use the following docker compose.

```
version: "3"
services:
    duplicati-monitor:
        container_name: duplicati-monitor
        image: rafa93m/duplicati-monitor
        ports:
            - 8000:8000
        environment:
            URI_NOTIFICATION: "tgram://<TOKEN_TELEGRAM_BOT>/<CHANEL_ID>/?format=markdown"
            TEMPLATE_SUCCESS: "💾 🟢 Backup: <Extra.backup-name>"
            TEMPLATE_ERROR: "💾 🔴 Backup <Extra.backup-name> failed 🔥 🔥"
        restart: unless-stopped
```

<div class="highlight highlight-source-yaml notranslate position-relative overflow-auto" dir="auto" id="bkmrk--16"><div class="zeroclipboard-container">  
</div></div>### Setup Duplicati

<div class="markdown-heading" dir="auto" id="bkmrk--17">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/RafaMunoz/duplicati-monitor#setup-duplicati)</div>Add theses two options for each backup you want to monitor:

- **send-http-result-output-format**: json
- **send-http-url**: http://**IP\_ADDRESS**:**PORT**/report

[![advanced-options](https://github.com/RafaMunoz/duplicati-monitor/raw/main/docs/img/advanced-options.png)](https://github.com/RafaMunoz/duplicati-monitor/blob/main/docs/img/advanced-options.png)

# Duplicati Dashboard

Link: [https://github.com/fabien-github/duplicati\_dashboard?tab=readme-ov-file#demo](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#demo)   
git clone [https://github.com/fabien-github/duplicati\_dashboard.git](https://github.com/fabien-github/duplicati_dashboard.git)

Duplicati Dashboard is a monitoring solution for [Duplicati](https://www.duplicati.com/).

It allows you to monitor your backups status, collects stats for each reports and alerts you by email when a backup fails. It is intended to be self-hosted and works with [docker-compose](https://docs.docker.com/compose/).

Everything is already pre-configured and ready to be deployed.

- [Duplicati Dashboard](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#duplicati-dashboard)
- [Demo](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#demo)
- [Quick Start](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#quick-start)
    - [Running with docker-compose](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#running-with-docker-compose)
    - [Setup Duplicati](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#setup-duplicati)
    - [Connect to your dashboard](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#connect-to-your-dashboard)
- [Configuration](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#configuration)
    - [Env file](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#env-file)
- [Notes](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#notes)
    - [Grafana configuration locked](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#grafana-configuration-locked)
    - [Backup over more than 30 days rotation](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#backup-over-more-than-30-days-rotation)
    - [Alerting graph](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#alerting-graph)
    - [Deleting removed backup data](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#deleting-removed-backup-data)
    - [Docker-compose](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#docker-compose)
- [Other informations](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#other-informations)
- [License](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#license)

# Demo

<div class="markdown-heading" dir="auto" id="bkmrk-" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#demo)</div>[![](https://github.com/fabien-github/duplicati_dashboard/raw/main/docs/img/demo.gif)](https://github.com/fabien-github/duplicati_dashboard/blob/main/docs/img/demo.gif)

> The right side of the video is not integrated in the dashboard. You can't control your backup with it.

# Quick Start

<div class="markdown-heading" dir="auto" id="bkmrk--3" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#quick-start)</div>### Running with docker-compose

<div class="markdown-heading" dir="auto" id="bkmrk--5" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#running-with-docker-compose)</div>```
git clone https://github.com/fabien-github/duplicati_dashboard.git
cd duplicati_dashboard
docker-compose up -d
```

<div class="zeroclipboard-container" id="bkmrk--7" style="text-align: justify;">  
</div>### Setup Duplicati

<div class="markdown-heading" dir="auto" id="bkmrk--8" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#setup-duplicati)</div>Add theses two options for each backup you want to monitor:

- **send-http-result-output-format:** json
- **send-http-url:** [http://localhost:8080](http://localhost:8080)

[![](https://github.com/fabien-github/duplicati_dashboard/raw/main/docs/img/backup_options_report_config.png)](https://github.com/fabien-github/duplicati_dashboard/blob/main/docs/img/backup_options_report_config.png)

> This assumes that your Duplicati instance is on the same host as your Duplicati Dashboard.

### Connect to your dashboard

<div class="markdown-heading" dir="auto" id="bkmrk--11" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#connect-to-your-dashboard)</div>[http://localhost:3000](http://localhost:3000)

Login: `admin` Password: `password`

> For email alerting, you need to configure a SMTP relay. See [Configuration &gt; Env file](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#env-file)

# Configuration

<div class="markdown-heading" dir="auto" id="bkmrk--13" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#configuration)</div>## Env file

<div class="markdown-heading" dir="auto" id="bkmrk--15" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#env-file)</div>The file [`config.env`](https://github.com/fabien-github/duplicati_dashboard/blob/main/config.env) is used to configure some options. It will be shared between the 3 containers.

Only use this default configuration for testing purposes.

Influxdb variable will create and setup the database only on the first startup.

<table id="bkmrk-variables-default-de" tabindex="0"><thead><tr><th>Variables</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td>DOCKER\_INFLUXDB\_INIT\_MODE</td><td>setup</td><td>[Automatically bootstrap the system](https://github.com/docker-library/docs/blob/master/influxdb/README.md#automated-setup)</td></tr><tr><td>DOCKER\_INFLUXDB\_INIT\_USERNAME</td><td>telegraf\_user</td><td>Influxdb superadmin user</td></tr><tr><td>DOCKER\_INFLUXDB\_INIT\_PASSWORD</td><td>telegraf\_password</td><td>Influxdb superadmin password</td></tr><tr><td>DOCKER\_INFLUXDB\_INIT\_ORG</td><td>telegraf\_org</td><td>Influxdb Organization (used by influxdb / telegraf / grafana)</td></tr><tr><td>DOCKER\_INFLUXDB\_INIT\_BUCKET</td><td>telegraf</td><td>Influxdb bucket to store reports (used by influxdb / telegraf / grafana)</td></tr><tr><td>DOCKER\_INFLUXDB\_INIT\_ADMIN\_TOKEN</td><td>telegraf\_token</td><td>Influxdb superadmin token (used by influxdb / telegraf / grafana)</td></tr><tr><td>DOCKER\_INFLUXDB\_INIT\_RETENTION</td><td> </td><td>Influxdb data retention, default will retain forever</td></tr><tr><td>INFLUXD\_REPORTING\_DISABLED</td><td>false</td><td>Disable [InfluxData telemetry](https://docs.influxdata.com/influxdb/v2.0/reference/config-options/#reporting-disabled)</td></tr><tr><td>TELEGRAF\_LISTENER\_PORT</td><td>8080</td><td>Port used by [http\_listener\_v2](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/http_listener_v2) input, endpoint for the reports sent by Duplicati</td></tr><tr><td>TELEGRAF\_LISTENER\_PATH</td><td>/</td><td>Path to listen to</td></tr><tr><td>GF\_SECURITY\_ADMIN\_USER</td><td>admin</td><td>Grafana superadmin user</td></tr><tr><td>GF\_SECURITY\_ADMIN\_PASSWORD</td><td>password</td><td>Grafana superadmin password</td></tr><tr><td>GF\_SERVER\_ROOT\_URL</td><td>[http://localhost:3000](http://localhost:3000)</td><td>Grafana URL, used in some templates like email notifications</td></tr><tr><td>GF\_DASHBOARDS\_DEFAULT\_HOME\_DASHBOARD\_PATH</td><td>/etc/grafana/provisioning/dashboards/duplicati\_dashboard.json</td><td>Force Duplicati dashboard by default on home page</td></tr><tr><td>GF\_SMTP\_ENABLED</td><td>false</td><td>[Set to true for email notifications](https://grafana.com/docs/grafana/latest/administration/configuration/#smtp)</td></tr><tr><td>GF\_SMTP\_HOST</td><td>localhost:25</td><td>SMTP relay server. \[host\]:\[port\]</td></tr><tr><td>GF\_SMTP\_FROM\_NAME</td><td>Grafana</td><td>Name of the email sender</td></tr><tr><td>GF\_SMTP\_USER</td><td> </td><td>In case of SMTP auth</td></tr><tr><td>GF\_SMTP\_PASSWORD</td><td> </td><td>In case of SMTP auth</td></tr><tr><td>GF\_SMTP\_FROM\_ADDRESS</td><td><admin@grafana.localhost></td><td>Address used when sending out emails</td></tr><tr><td>GF\_SMTP\_EHLO\_IDENTITY</td><td>${HOSTNAME}</td><td>Name to be used as client identity for EHLO in SMTP dialog (Default will be the container ID)</td></tr><tr><td>GF\_SMTP\_STARTTLS\_POLICY</td><td> </td><td>“OpportunisticStartTLS”, “MandatoryStartTLS”, “NoStartTLS”</td></tr><tr><td>NOTIFIER\_EMAIL\_RECIPIENT</td><td><example@example.com></td><td>Recipients for email notification (separated by a semicolon)</td></tr><tr><td>NOTIFIER\_EMAIL\_REMINDER\_ENABLE</td><td>true</td><td>Re-send an email if alerts are still active</td></tr><tr><td>NOTIFIER\_EMAIL\_REMINDER\_FREQUENCY</td><td>2h</td><td>Delay between email reminders</td></tr></tbody></table>

# Notes

<div class="markdown-heading" dir="auto" id="bkmrk--17" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#notes)</div>## Grafana configuration locked

<div class="markdown-heading" dir="auto" id="bkmrk--19" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#grafana-configuration-locked)</div>The dashboard is locked by the Grafana provisioning system. You can't edit the datasource, the dashboard or the alert notifier from the UI. You will need to copy the dashboard or disable the provisioning configuration.

Dashboard path: `./grafana/provisioning/dashboards/duplicati_dashboard.json`

The idea is to keep the stack easy to deploy for everyone without investing time to learn Grafana configuration.

Feel free to fork the project or directly edit files on your own.

More information [here](https://grafana.com/docs/grafana/latest/administration/provisioning/).

## Backup over more than 30 days rotation

<div class="markdown-heading" dir="auto" id="bkmrk--21" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#backup-over-more-than-30-days-rotation)</div>- Grafana will discover your backups name from the reports but only over the last 90 days. So if your backups are scheduled for more than 90 days, you will need to edit the request of the variable `Backup` in the dashboard configuration:

```
from(bucket: v.defaultBucket)
  |> range(start: -90d)
  |> filter(fn: (r) => true)
  |> toString()
  |> group(columns: ["backup-name"])
  |> distinct(column: "backup-name")
  |> keep(columns: ["_value"])
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--23" style="text-align: justify;"><div class="zeroclipboard-container">  
</div></div>- Last reported status / Last reported variations / Alerting graph are based over the past 30 days. You will need to adapt each panel requests if your backups are scheduled over more than 30 days.

```
import "influxdata/influxdb/schema"

from(bucket: v.defaultBucket)
  |> range(start: -30d)
  ...
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--24" style="text-align: justify;"><div class="zeroclipboard-container">  
</div></div>- In [v2](https://github.com/fabien-github/duplicati_dashboard/releases/tag/v1.0.0), alerts have their own provisioning file and query range can be edited [here](https://github.com/fabien-github/duplicati_dashboard/blob/3e1d558d54c6b3ecbb7ed67627a812c5dd060f31/grafana/provisioning/alerting/duplicati_alert.yml#L30).

## Alerting graph

<div class="markdown-heading" dir="auto" id="bkmrk--25" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#alerting-graph)</div>The section "Alerting graph" is only used to trigger an alert when a backup fails. This is due to the lack of grafana alert support on other panel type. [\#6983](https://github.com/grafana/grafana/issues/6983)

Backups status will be checked every minutes. An alert will be triggered after a pending status of 10min. Same delays are used on the recovery.

Warning reports don't trigger an alert.

## Deleting removed backup data

<div class="markdown-heading" dir="auto" id="bkmrk--27" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#deleting-removed-backup-data)</div>After getting inside the influxdb container:

```
influx delete \
  --org telegraf_org \
  --bucket telegraf \
  --token "telegraf_token" \
  --start 1970-01-01T00:00:00Z \
  --stop $(date +"%Y-%m-%dT%H:%M:%SZ") \
  --predicate '_measurement="duplicati" AND "backup-name"="backup_to_delete"'
```

<div class="highlight highlight-source-shell notranslate position-relative overflow-auto" dir="auto" id="bkmrk--29" style="text-align: justify;"><div class="zeroclipboard-container">  
</div></div>## Docker-compose

<div class="markdown-heading" dir="auto" id="bkmrk--30" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#docker-compose)</div>- **Telegraf**: Receive JSON reports from Duplicati.
- **Influxdb**: Store reports converted by Telegraf.
- **Grafana**: Requests Influxdb to generate dashboard and alerts.

Telegraf endpoint provides a limited [HTTP autentification](https://github.com/influxdata/telegraf/tree/master/plugins/inputs/http_listener_v2).  
The configuration file is located here : `./telegraf/telegraf.conf`

Feel free to add a proxy like traefik or nginx to protect the stack on an unsecure network. (TLS, IP Restrictions, ...)

# Other informations

<div class="markdown-heading" dir="auto" id="bkmrk--32" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#other-informations)</div>- Not sure of the scalabilty, requests to the database are not efficients. Timeseries databases are not really adapted for this kind of data. This is mainly due to the nested and uneven json format from the reports and the variation time between reports.
- Features are limited directly by the stack itself. For example, it's nearly impossible to add a managment system for the backups.
- This project has no link with the development of Duplicati and his team.

# License

<div class="markdown-heading" dir="auto" id="bkmrk--34" style="text-align: justify;">[<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewbox="0 0 16 16" width="16"></svg>](https://github.com/fabien-github/duplicati_dashboard?tab=readme-ov-file#license)</div>Distributed under the GNU General Public License v3.0 License. See [LICENSE](https://github.com/fabien-github/duplicati_dashboard/blob/main/LICENSE) for more information.

# Duplicati Dashboard2

Link: [https://github.com/wchorski/duplicati-dashboard](https://github.com/wchorski/duplicati-dashboard) git clone [https://github.com/wchorski/duplicati-dashboard.git](https://github.com/wchorski/duplicati-dashboard.git)

A NodeJS based server that collects JSON data from Duplicati backup logs  
📦 Tech

 Frontend: NextJS  
 API: NextJS  
 Database: InfluxDB

 \[!warning\] Backups sharing the same name will cause issues. The backup's name must be unique across all Duplicati instances, it will be used as an ID for logging. MUST BE URL FRIENDLY example: "Laptop--Home\_Folder\_Backup", "Desktop--Home\_Folder\_Backup" is a good naming convention.

Usecase

Initally this was just some middle ware that serves as an endpoint for JSON friendly monitoring apps, but I also built a simple UI so it could be used as a standalone app.  
Duplicati Setup

you can either add these settings for the globally or per backup in the Advanced options

 send-http-result-output-format = json  
 send-http-url = "http://APPSDOMAIN/api/backups"

API

Here is a breakdown of what endpoints and search parameters that can be passed through.  
URL Breakdown

http://APPDOMAIN/backups/BACKUP\_ID?start=-5h&amp;first=true

 BACKUP\_ID =&gt; the id (or name) of the backup saved  
 stuff after the "?" search query sets range of time of pulled data  
 start =&gt; how far back to you want to start pulling data i.e.  
 -40d 40 days ago \[the default\]  
 -5h 5 hours ago  
 -60m 60 miniutes ago  
 1999-12-31T00:00:00 starting on December 31st, 1999  
 1694117521 starting on this UNIX time (seconds)  
 stop =&gt; the end of the range  
 now() =&gt; my current time \[the default\]  
 all the other examples above as long as the date is after the start  
 both query parameters can be omitted  
 last =&gt; set to true if you'd like the last recorded point in the table  
 can also use the http://localhost:3000/api/backups/last/BACKUP\_ID endpoint for cleaner GET (this endpoint also takes start and stop query parameters)  
 first =&gt; same as last but returns the first point of recoreded data within the range

 \[!note\] make sure relative dates have a negative i.e. -5h as your are looking back in time. Positive time values will cause errors

Examples  
query url  
all backup stats in database http://APPDOMAIN/backups  
single backup stats http://APPDOMAIN/backups/BACKUP\_ID  
last recorded backup stat http://APPDOMAIN/backups/last/BACKUP\_ID  
same as above http://APPDOMAIN/backups/BACKUP\_ID?last=true  
last recorded backup stat in the last 5 hours http://APPDOMAIN/backups/last/BACKUP\_ID?start=-5h  
⚙️ Development

 git clone https://github.com/wchorski/duplicati-dashboard.git &amp;&amp; cd duplicati-dashboard  
 cp .env.template .env.local  
 set up InfluxDB instance  
 get InfluxDB API Token for .env.local  
 yarn install  
 yarn dev

🏭 Production

 git clone https://github.com/wchorski/duplicati-dashboard.git &amp;&amp; cd duplicati-dashboard  
 cp .env.template .env  
 the INFLUX\_TOKEN in .env should be a long ~88 character string  
 docker compose up -d

Home Assistant

rest:   
\- authentication: basic  
 username: "admin"  
 password: "password"  
 scan\_interval: 86400  
 resource: http://APPDOMAIN.lan/api/backups/last/DUPLICATI\_ID  
 sensor:  
\- name: "duplicati-DUPLICATI\_ID-status"  
 value\_template: "{{ value\_json.status }}"  
\- name: "duplicati-DUPLICATI\_ID-time"  
 value\_template: &gt;  
 {% set thistime = value\_json.time %}  
 {{ as\_timestamp(thistime) | timestamp\_custom("%Y %M, %d %H:%M") }}

\#Todo

 create dynamic nav based on unique duplicati\_ids from database  
 add FAQ as a page inside the app  
 mobile friendly (almost there)  
 graph trends in app  
 Home Assistant Template sensor  
 Don't be lazy and figure out Types in TableClient.tsx component  
 get real data for screenshots  
 why is bg tile image weird when scrolling on mobile?  
 human readable bytes formatter (gb tb)  
 human readable duration formatter