{"id":16293675,"url":"https://github.com/ngosang/restic-exporter","last_synced_at":"2025-04-09T06:11:16.001Z","repository":{"id":65111562,"uuid":"575002211","full_name":"ngosang/restic-exporter","owner":"ngosang","description":"Prometheus exporter for the Restic backup system","archived":false,"fork":false,"pushed_at":"2025-02-15T17:32:04.000Z","size":332,"stargazers_count":102,"open_issues_count":6,"forks_count":23,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-02T02:11:45.077Z","etag":null,"topics":["backup","docker","exporter","prometheus","python","restic"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ngosang.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-06T14:40:00.000Z","updated_at":"2025-03-25T15:41:23.000Z","dependencies_parsed_at":"2024-12-17T00:11:32.769Z","dependency_job_id":"b43a8be0-4475-4a0d-a2de-fca0266d0b6f","html_url":"https://github.com/ngosang/restic-exporter","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngosang%2Frestic-exporter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngosang%2Frestic-exporter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngosang%2Frestic-exporter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ngosang%2Frestic-exporter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ngosang","download_url":"https://codeload.github.com/ngosang/restic-exporter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247987285,"owners_count":21028895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backup","docker","exporter","prometheus","python","restic"],"created_at":"2024-10-10T20:12:02.554Z","updated_at":"2025-04-09T06:11:15.982Z","avatar_url":"https://github.com/ngosang.png","language":"Python","funding_links":["https://www.paypal.com/paypalme/diegoheras0xff"],"categories":["Python","Other"],"sub_categories":[],"readme":"# ngosang/restic-exporter\n\n[![Latest release](https://img.shields.io/github/v/release/ngosang/restic-exporter)](https://github.com/ngosang/restic-exporter/releases)\n[![Docker Pulls](https://img.shields.io/docker/pulls/ngosang/restic-exporter)](https://hub.docker.com/r/ngosang/restic-exporter/)\n[![Donate PayPal](https://img.shields.io/badge/Donate-PayPal-yellow.svg)](https://www.paypal.com/paypalme/diegoheras0xff)\n[![Donate Bitcoin](https://img.shields.io/badge/Donate-Bitcoin-f7931a.svg)](https://www.blockchain.com/btc/address/14EcPN47rWXkmFvjfohJx2rQxxoeBRJhej)\n[![Donate Ethereum](https://img.shields.io/badge/Donate-Ethereum-8c8c8c.svg)](https://www.blockchain.com/eth/address/0x0D1549BbB00926BF3D92c1A8A58695e982f1BE2E)\n\nPrometheus exporter for the [Restic](https://github.com/restic/restic) backup system.\n\n## Install\n\n### From source code\n\nRequirements:\n * Python 3\n * [prometheus-client](https://github.com/prometheus/client_python)\n\n```bash\npip install -r /requirements.txt\n\nexport RESTIC_REPOSITORY=/data\nexport RESTIC_PASSWORD_FILE=/restic_password_file\npython restic-exporter.py\n```\n\n### Docker\n\nDocker images are available in [GHCR](https://github.com/ngosang/restic-exporter/pkgs/container/restic-exporter) and [DockerHub](https://hub.docker.com/r/ngosang/restic-exporter).\n\n```bash\ndocker pull ghcr.io/ngosang/restic-exporter\nor\ndocker pull ngosang/restic-exporter\n```\n\n#### Supported Architectures\n\nThe architectures supported by this image are:\n\n* linux/386\n* linux/amd64\n* linux/arm/v6\n* linux/arm/v7\n* linux/arm64/v8\n* linux/ppc64le\n* linux/s390x\n\n#### docker-compose\n\nCompatible with docker-compose v2 schemas:\n\n```yaml\n---\nversion: '2.1'\nservices:\n  restic-exporter:\n    image: ngosang/restic-exporter\n    container_name: restic-exporter\n    environment:\n      - TZ=Europe/Madrid\n      - RESTIC_REPOSITORY=/data\n      - RESTIC_PASSWORD=\u003cpassword_here\u003e\n      # - RESTIC_PASSWORD_FILE=\u003c/file_with_password_here\u003e\n      - REFRESH_INTERVAL=1800 # 30 min\n    volumes:\n      - /host_path/restic/data:/data\n    ports:\n      - \"8001:8001\"\n    restart: unless-stopped\n```\n\n#### docker cli\n\n```bash\ndocker run -d \\\n  --name=restic-exporter \\\n  -e TZ=Europe/Madrid \\\n  -e RESTIC_REPOSITORY=/data \\\n  -e RESTIC_PASSWORD=\u003cpassword_here\u003e \\\n  -e REFRESH_INTERVAL=1800 \\\n  -p 8001:8001 \\\n  --restart unless-stopped \\\n  ngosang/restic-exporter\n```\n\n## Configuration\n\nThis Prometheus exporter is compatible with all [backends supported by Restic](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html).\nSome of them need additional environment variables for the secrets.\n\nAll configuration is done with environment variables:\n\n- `RESTIC_REPOSITORY`: Restic repository URL. All backends are supported. Examples:\n  * Local repository: `/data`\n  * REST Server: `rest:http://user:password@127.0.0.1:8000/`\n  * Amazon S3: `s3:s3.amazonaws.com/bucket_name`\n  * Backblaze B2: `b2:bucketname:path/to/repo`\n  * Rclone (see notes below): `rclone:gd-backup:/restic`\n\n- `RESTIC_PASSWORD`: Restic repository password in plain text. This is only\nrequired if `RESTIC_PASSWORD_FILE` is not defined.\n- `RESTIC_PASSWORD_FILE`: File with the Restic repository password in plain\ntext. This is only required if `RESTIC_PASSWORD` is not defined. Remember\nto mount the Docker volume with the file.\n- `AWS_ACCESS_KEY_ID`: (Optional) Required for Amazon S3, Minio and Wasabi\nbackends.\n- `AWS_SECRET_ACCESS_KEY`: (Optional) Required for Amazon S3, Minio and Wasabi\nbackends.\n- `B2_ACCOUNT_ID`: (Optional) Required for Backblaze B2 backend.\n- `B2_ACCOUNT_KEY`: (Optional) Required for Backblaze B2 backend.\n- `REFRESH_INTERVAL`: (Optional) Refresh interval for the metrics in seconds.\nComputing the metrics is an expensive task, keep this value as high as possible.\nDefault is `60` seconds.\n  - **WARNING**: With default settings, downloading from remote repositories\nmay be costly if using this exporter with a remote Cloud-based restic repository\n(e.g. GCP GCS, Amazon S3). This may cause a surprisingly high spike in your\ninfrastructure costs (e.g. for small restic repositories that don't download\nfrequently, this may increase your costs by multiple orders of magnitude).\nConsider setting `REFRESH_INTERVAL` to considerably higher values (e.g. `86400`\nfor once per day) to lower this impact.\n- `LISTEN_PORT`: (Optional) The address the exporter should listen on. The\ndefault is `8001`.\n- `LISTEN_ADDRESS`: (Optional) The address the exporter should listen on. The\ndefault is to listen on all addresses.\n- `LOG_LEVEL`: (Optional) Log level of the traces. The default is `INFO`.\n- `EXIT_ON_ERROR`: (Optional) Shutdown exporter on any `restic` error. Default\nis `Flase` (only log error, such as network error with Cloud backends).\n- `NO_CHECK`: (Optional) Do not perform `restic check` operation for performance\nreasons. Default is `False` (perform `restic check`).\n- `NO_STATS`: (Optional) Do not collect per backup statistics for performance\nreasons. Default is `False` (collect per backup statistics).\n- `NO_LOCKS`: (Optional) Do not collect the number of locks. Default is `False` (collect the number of locks).\n- `INCLUDE_PATHS`: (Optional) Include snapshot paths for each backup. The paths are separated by commas. Default is `False` (not collect the paths).\n- `INSECURE_TLS`: (Optional) skip TLS verification for self-signed certificates. Default is `False` (not skip).\n\n### Configuration for Rclone\n\nRclone is not included in the Docker image. You have to mount the Rclone executable and the Rclone configuration from the host machine. Here is an example with docker-compose:\n\n```yaml\nversion: '2.1'\nservices:\n  restic-exporter:\n    image: ngosang/restic-exporter\n    container_name: restic-exporter\n    environment:\n      - TZ=Europe/Madrid\n      - RESTIC_REPOSITORY=rclone:gd-backup:/restic\n      - RESTIC_PASSWORD= \n      - REFRESH_INTERVAL=1800 # 30 min\n    volumes:\n      - /host_path/restic/data:/data\n      - /usr/bin/rclone:/usr/bin/rclone:ro\n      - /host_path/restic/rclone.conf:/root/.config/rclone/rclone.conf:ro\n    ports:\n      - \"8001:8001\"\n    restart: unless-stopped\n```\n\n## Exported metrics\n\n```bash\n# HELP restic_check_success Result of restic check operation in the repository\n# TYPE restic_check_success gauge\nrestic_check_success 1.0\n# HELP restic_locks_total Total number of locks in the repository\n# TYPE restic_locks_total counter\nrestic_locks_total 1.0\n# HELP restic_snapshots_total Total number of snapshots in the repository\n# TYPE restic_snapshots_total counter\nrestic_snapshots_total 100.0\n# HELP restic_backup_timestamp Timestamp of the last backup\n# TYPE restic_backup_timestamp gauge\nrestic_backup_timestamp{client_hostname=\"product.example.com\",client_username=\"root\",client_version=\"restic 0.16.0\",snapshot_hash=\"20795072cba0953bcdbe52e9cf9d75e5726042f5bbf2584bb2999372398ee835\",snapshot_tag=\"mysql\",snapshot_tags=\"mysql,tag2\",snapshot_paths=\"/mysql/data,/mysql/config\"} 1.666273638e+09\n# HELP restic_backup_files_total Number of files in the backup\n# TYPE restic_backup_files_total counter\nrestic_backup_files_total{client_hostname=\"product.example.com\",client_username=\"root\",client_version=\"restic 0.16.0\",snapshot_hash=\"20795072cba0953bcdbe52e9cf9d75e5726042f5bbf2584bb2999372398ee835\",snapshot_tag=\"mysql\",snapshot_tags=\"mysql,tag2\",snapshot_paths=\"/mysql/data,/mysql/config\"} 8.0\n# HELP restic_backup_size_total Total size of backup in bytes\n# TYPE restic_backup_size_total counter\nrestic_backup_size_total{client_hostname=\"product.example.com\",client_username=\"root\",client_version=\"restic 0.16.0\",snapshot_hash=\"20795072cba0953bcdbe52e9cf9d75e5726042f5bbf2584bb2999372398ee835\",snapshot_tag=\"mysql\",snapshot_tags=\"mysql,tag2\",snapshot_paths=\"/mysql/data,/mysql/config\"} 4.3309562e+07\n# HELP restic_backup_snapshots_total Total number of snapshots\n# TYPE restic_backup_snapshots_total counter\nrestic_backup_snapshots_total{client_hostname=\"product.example.com\",client_username=\"root\",client_version=\"restic 0.16.0\",snapshot_hash=\"20795072cba0953bcdbe52e9cf9d75e5726042f5bbf2584bb2999372398ee835\",snapshot_tag=\"mysql\",snapshot_tags=\"mysql,tag2\",snapshot_paths=\"/mysql/data,/mysql/config\"} 1.0\n# HELP restic_scrape_duration_seconds Amount of time each scrape takes\n# TYPE restic_scrape_duration_seconds gauge\nrestic_scrape_duration_seconds 166.9411084651947\n```\n\n## Prometheus config\n\nExample Prometheus configuration:\n\n```yaml\nscrape_configs:\n  - job_name: 'restic-exporter'\n    static_configs:\n      - targets: ['192.168.1.100:8001']\n```\n\n## Prometheus / Alertmanager rules\n\nExample Prometheus rules for alerting:\n\n```yaml\n  - alert: ResticCheckFailed\n    expr: restic_check_success == 0\n    for: 5m\n    labels:\n      severity: critical\n    annotations:\n      summary: Restic check failed (instance {{ $labels.instance }})\n      description: Restic check failed\\n  VALUE = {{ $value }}\\n  LABELS = {{ $labels }}\n\n  - alert: ResticOutdatedBackup\n    # 1209600 = 15 days\n    expr: time() - restic_backup_timestamp \u003e 1209600\n    for: 0m\n    labels:\n      severity: critical\n    annotations:\n      summary: Restic {{ $labels.client_hostname }} / {{ $labels.client_username }} backup is outdated\n      description: Restic backup is outdated\\n  VALUE = {{ $value }}\\n  LABELS = {{ $labels }}\n```\n\n## Grafana dashboard\n\nThere is a reference Grafana dashboard in [grafana/grafana_dashboard.json](./grafana/grafana_dashboard.json).\n\n![](./grafana/grafana_dashboard.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngosang%2Frestic-exporter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fngosang%2Frestic-exporter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fngosang%2Frestic-exporter/lists"}