calcardbackup: Kalender- und Adressbuchbackup von ownCloud / Nextcloud

Wer einen eigenen caldav- und carddav-Server betreibt, um Kalender und Adressbücher über verschiedene Geräte hinweg synchron zu halten, sollte sich auch selbst um Sicherungen kümmern. Bei Nextcloud / ownCloud kann man aus dem Webfrontend Adressbücher und Kalender einzeln als .vcf- bzw. .ics-Datei exportieren. Das ist superpraktisch, denn man kann mithilfe solcher Dateien verlorene Adressbücher und Kalender sehr einfach wiederherstellen. Aber eigentlich ist der Export auch ziemlich umständlich – vor allem wenn man mehrere Kalender pflegt und ein Backup relativ regelmäßig herstellen möchte. Das wollte ich für mich unbedingt automatisieren!

Zunächst habe ich ein Bash-Skript geschrieben, das genau auf meinen Anwendungsfall zurecht geschnitten war. Im Lauf der Zeit wurde das Skript erweitert und verbessert, da neue Kalender angelegt wurden und auch zwei Freunde Bedarf für eine Backup von Nextcloud-Kalendern und -Adressbüchern hatten.

Da die Anforderungen verschieden waren (z.B. ältere ownCloud-Version und aktuellere Nextcloud-Version) wurde das Skript immer umfangreicher. Inzwischen funktioniert das Skript mit Installationen von Nextcloud / ownCloud >= 5.0 mit MySQL/MariaDB, PostgreSQL oder SQLite3. Ich habe Wert auf gute Rückmeldungen im Fehlerfall gelegt. Es stehen verschiedene Optionen zur Verfügung, um das Verhalten des Skripts zu beeinflussen.

Das Skript könnte auch für andere ownCloud / Nextcloud Nutzer interessant sein, daher hatte ich es auf GitHub veröffentlicht. Nach der Übernahme GitHubs durch Microsoft erfolgte 2020 ein Umzug des Repositories zu Codeberg – seitdem ist nur dort die aktuelle Version zu finden:
https://codeberg.org/BernieO/calcardbackup

Das Bash-Skript benötigt neben einer Nextcloud / ownCloud Installation nur das Clientprogramm der zugehörigen Datenbank (mysql / mariadb, psql oder sqlite3). Das dürfte sowieso auf Systemen vorhanden sein auf denen Nextcloud oder ownCloud läuft. Entwickelt wird das Skript unter Debian. Die Rückmeldungen des Skripts sind daher auf Debian zurechtgeschnitten. Erfolgreich getestet wurde das Skript aber auch mit Ubuntu, FreeBSD, SunOS und Darwin.

Was genau macht das Skript?

Das Skript liest Versionsnummer, Datenbanktyp und Datenbankzugangsdaten aus der Konfigurationsdatei config.php von Nextcloud / ownCloud aus. Danach werden in der Datenbank vorhandene Kalender und Adressbücher aller Benutzer exportiert und in einer komprimierten Datei lokal gespeichert. Das war auch schon alles. Zu keinem Zeitpunkt verlassen irgendwelche Daten das System.

Installation

In ein Verzeichnis wechseln, in dem das Script gespeichert werden soll, und das Repository von Codeberg.org klonen und in das geklonte Verzeichnis wechseln (unbedingt außerhalb des Webserver-Verzeichnisses!):

cd /usr/local/bin
git clone https://codeberg.org/BernieO/calcardbackup.git
cd calcardbackup

Den ganzen Ordner dem Webserver-User (hier www-data) zu eigen machen:

chown -R www-data:www-data .

Dann kann das Skript mit Pfadangabe zu Nextcloud / ownCloud (im Beispiel hier /var/www/nextcloud) aufgerufen werden. Da das Skript Zugriff auf den Ordner des Webservers braucht, wird es hier als User www-data gestartet. Falls noch etwas nachinstalliert werden muss, oder eine Konfigurationseinstellung fehlt, wird das in der Ausgabe des Scripts ersichtlich sein.

sudo -u www-data ./calcardbackup /var/www/nextcloud

Nach erfolgreichem Durchlauf des Scripts findet sich das Backup im Ordner backups/. Die Backups mit der Endung tar.gz lassen sich mit folgendem Befehl entpacken:

tar -xzf calcardbackup-2017-03-23.tar.gz

Eine regelmäßige Ausführung kann man per cronjob veranlassen, indem man folgende Zeile in die Datei /etc/crontab einfügt (so wird täglich um 22:00 Uhr ein Backup angefertigt):

00 22   * * * www-data  /usr/local/bin/calcardbackup/calcardbackup /var/www/nextcloud

Das Verhalten des Skripts kann durch verschiedene Optionen beeinflusst werden (unter ihnen auch eine, um Nextcloud Deck-Boards zu exportieren). Details finden sich in den beiden README-Dateien des Repositories. Diese werden aktuell gehalten, erklären alle Optionen ausführlich und enthalten zahlreiche Beispiele auf Deutsch und Englisch.

Wenn jemand etwas mit dem Script anfangen kann, würde ich mich über Kommentare sehr freuen. Falls Fehler gefunden werden, versuche ich diese zu korrigieren.

______________________________
Changelog:
23.02.2026: komplette Überarbeitung und Entfernung von zahlreichen veralteten Textabschnitten. In diesem Blogbeitrag steht nun nur noch Grundlegendes über calcardbackup. Eine aktuelle ausführliche Anleitung mit Beispielen findet sich in den README-Dateien des Repositories ( Deutsch / Englisch ).

21 Kommentare on "calcardbackup: Kalender- und Adressbuchbackup von ownCloud / Nextcloud"


  1. Hallo Bernhard,

    gibt es Erfahrungen zur Installation und Einrichtung in TrueNAS Scale? Und beruht das Skript darauf, das ein db_dump durchgeführt wurde? Ich finde keine *_cards Dateien oder ähnliches in meinem postgres-Ordner.
    Wie man merkt: Ich kriege aktuell keinen Fuß an den Boden und wäre unheimlich dankbar für Support – das Skript ist per-se genau, was ich suche.

    Beste Grüße
    Ben

    Antworten

    1. Hallo Ben,

      mit TrueNAS Scale kenne ich mich nicht aus.

      Das Script greift jedenfalls über den Datenbankserver auf die Daten zu. Mit einem Datenbank-dump oder mit den Rohdateien der Datenbank kann das Script nichts anfangen.
      Wenn Nextcloud/ownCloud läuft, genügt dem Script normalerweise die Angabe des Pfads zur Nextcloud/ownCloud Installation wie im README beschrieben.

      Viele Grüße
      Bernhard.

      Antworten

  2. hallo bob –

    wirklich tolles und brauchbares script! ich habe nextcloud 14 auf einem reseller am laufen, hab nur limitierten shell zugang. konnte aber alles aus git laden, direkt in den ordner cgi-bin. hab die conf datei sowohl mit datenbank abfrage und php abfrage ausprobiert – beides mal folgender output:

    /cgi-bin/calcardbackup> ./calcardbackup
    
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    +
    + Fri Oct 12 10:00:21 UTC 2018 —> START calcardbackup ver. 0.7.2 (19.09.2018), AGPL-3.0
    + Checking dependencies and preparing…
    + Using configuration file /cgi-bin/calcardbackup/calcardbackup.conf, ignoring all other command line options.
    + Using URL https://www.xy.z
    + Nextcloud 14.0.1 detected.
    + Database of chosen Nextcloud installation is MySQL/MariaDB.
    + Looking for calendars in your Nextcloud:
    Could not open required defaults file: /dev/fd/63
    Fatal error in defaults handling. Program aborted

    ich hab nur eine user (keinen extra web-user), und kann das script auch nicht mit sudo laufen lassen…
    gibt es hier eine lösung?

    danke schon mal im voraus, benjamin

    Antworten

    1. Hallo Benjamin,

      wir standen vor einiger Zeit schon per E-Mail in Kontakt wegen deines Kommentars. Nun kommt noch spät eine Antwort hier im Blog. Denn mit Version 2.0 kommt calcardbackup mit einem kleinen PHP-Skript mithilfe dessen calcardbackup möglicherweise auf Hosting Umgebungen ohne shell-Zugang ausgeführt werden kann. Details finden sich im README des Repo auf codeberg – daher spare ich mir hier weitere Erklärungen.

      Vielleicht hilft dir das ja weiter – vielleicht hast du aber auch schon eine andere Lösung gefunden.

      Viele Grüße
      Bernhard.

      Antworten

  3. Hi Bob,

    ich hab mal wieder ein kleines Problemchen mit deinem wunderbaren script.
    Bei mir mag das script die Datenbankabfrage nicht.

    Ich bin auf pgsql Datenbank geswitcht.
    Nun hakt das script an folgender Stelle:

    ############################################################
    [query_database() { # gets details of calendars/addressbooks from database # see next lines for description of arguments ${1} and ${2}
    table=“${1}“ # ${table_calendars} or ${table_addressbooks} item=“${2}“ # „calendar“ or „addressbook“, just a verbal description, needed for output messages _output echo „+ Looking for ${item}s in your ${productname}:“ # change of directory needed for SQLite3, because ${datadirectory} could contain spaces and # sqlite3 would then need „${dboptions}“ to avoid bashs word splitting, but mysql needs ${dboptions} word-splitted: [[ „${dbtype}“ == „sqlite3“ ]] && cd „${datadirectory}“ # check if table exists: [[ „${dbtype}“ == „mysql“ && „${snap}“ == „no“ ]] && check_table=“$(mysql —defaults-extra-file=<(printf „[client]\nuser = %s\npassword = \“%s\“\nhost = %s\n%s“ „${dbuser}“ „${dbpassword}“ „${dbhost}“ „${dbprotocol}“) „${dbname}“ -e „show tables like ‚${table}‘“)“ [[ „${dbtype}“ == „mysql“ && „${snap}“ == „yes“ ]] && check_table=“$(nextcloud.mysql-client —defaults-extra-file=<(printf „[client]\nuser = %s\npassword = \“%s\“\nhost = %s\n%s“ „${dbuser}“ „${dbpassword}“ „${dbhost}“ „${dbprotocol}“) „${dbname}“ -e „show tables like ‚${table}‘“)“ [[ „${dbtype}“ == „sqlite3“ ]] && check_table=“$(sqlite3 owncloud.db „SELECT name FROM sqlite_master WHERE type=‚table‘ AND name=‘${table}‘“)“
    
    #—————— Bis hierhier funnktioniert noch alles ———————-#
    [[ „${dbtype}“ == „pgsql“ ]] && check_table=“$(PGPASSWORD=“${dbpassword}“ psql „${dbhost}“ „${dbprotocol}“ -U „${dbuser}“ -d „${dbname}“ -qtc „SELECT * FROM ${table}“ 2>/dev/null)“
    
    #—————— Nach der Anweisung nicht mehr ———————-#
    if [[ „${check_table:-}“ == “” ]]; then _output echo „+ Tabelle existiert“]
    
    ############################################################

    Der Output des scipts sieht wie folgt aus.

    ….cloud/calcardbackup-master $ sudo -u www-data ./calcardbackup -c calcardbackup.conf
    
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    +
    + Mo 17. Sep 19:22:32 CEST 2018 —> START calcardbackup ver. 0.7.1 (13.09.2018), AGPL-3.0
    + Checking dependencies and preparing…
    + Using configuration file /home/pi/Nextcloud/calcardbackup-master/calcardbackup.conf, ignoring all other command line options.
    + Using URL „mein URL“
    + Nextcloud 13.0.4 detected.
    + Database of chosen Nextcloud installation is PostgreSQL.
    + Looking for calendars in your Nextcloud:
    
    ]

    Hast du hier einen Idee was das Problem sein könnte?

    Vielen Dank im voraus.
    Gruß Steffen

    Antworten

    1. Durch einen kurzen Mailwechsel hat sich herausgestellt, dass der Fehler an einem Tippfehler im Datenbankpasswort lag.
      Dass keine aussagekräftige Fehlermeldung ausgegeben wurde, ist in Version 0.7.2 vom 19.09.2018 behoben.

      Antworten

  4. Hallo Bob,

    vielen Dank für dieses tolle Script!

    Es läuft super, wenn ich die Username:Passwort – Kombination, für alle User in der user.txt verwende. Ich möchte aber gerne die „-i“ Variante nutzen und bekomme dann folgenden Fehler:

    su -c „/usr/local/bin/calcardbackup/calcardbackup ‚/var/www/html‘ -f -i“ www-data -s /bin/bash
    
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    +
    + Wed Aug 15 09:34:49 UTC 2018 —> START calcardbackup ver. 0.6.0 (08.08.2018), AGPL-3.0
    + Checking dependencies and preparing…
    + Using URL https://nc.XXXX.de
    + Nextcloud 13.0.4 detected.
    + Database of chosen Nextcloud installation is MySQL/MariaDB.
    + Looking for calendars in your Nextcloud:
    + Saving calendar Dasi-Personal.ics……success!
    + Saving calendar Dasi-Personal_shared_by_test.ics……success!
    + Looking for addressbooks in your Nextcloud:
    /usr/local/bin/calcardbackup/calcardbackup: line 731: temp_principal: unbound variable

    Was mache ich falsch?

    MfG.
    Heiner

    Antworten

    1. Hallo Heiner,
      du hast gar nichts falsch gemacht, sondern ich: das Skript meckert wegen einer nicht deklarierten Variable, weil es versucht, geteilte Adressbücher zu sichern. Bei deiner Installation sind aber keine geteilten Adressbücher der angegebenen Nutzer vorhanden.
      Ich habe den Fehler gerade mit Version 0.6.1 behoben.
      Danke für den Hinweis!

      Antworten

  5. Hi Bob,

    echt cooles Tool von Dir. Danke schonmal
    Habe da nur eine kleine Frage zu dem Parameter --include-shares.

    Sollen damit Kalender von andere USERN gesichert werden, die diesen mit mir geteilt haben oder die Kalender von mir, den ich mit anderen geteilt habe.

    Ich habe den Kalender von meiner Freundin an mich geteilt. Dieser wird aber nicht mitgesichert. In meiner CONFIG habe ich den Parameter wie folgt gesetzt.

    < include_shares=„yes“ >

    Und mein Abruf sieht wie folgt aus:

    < sudo -u www-data ./calcardbackup -i -c calcardbackup.conf >
    Antworten

    1. Mit der Option -i|--include-shares werden Kalender von Benutzern gesichert, die diese mit einem User geteilt haben, der in der users.txt eingetragen ist. Bei deinem Aufruf des Skriptes kannst du das -i weglassen: wenn man eine Konfigurationsdatei (über die Option -c) benutzt, werden auf der Kommandozeile übergebene Optionen von den in der Konfigurationsdatei angegebenen Werten überschrieben.

      Nach etwas Mailwechsel mit mir hat Steffen herausgefunden, dass an Gruppen geteilte Kalender/Adressbücher von calcardbackup nicht berücksichtigt werden, obwohl mit der --include-shares-Option aufgerufen.
      Dies ist ein Fehler von calcardbackup, der in der nächsten Version des Skripts (v0.2.2) behoben sein wird.

      Antworten

  6. Hallo Bernhard,
    wieder mal ein Problem: Bin von NC10 und Raspbian umgestiegen auf NC12 und Archlinux (auf Raspi3).
    Kriege jetzt beim Backup folgenden Fehler:

    ERROR 2005 (HY000): Unknown MySQL server host ‚localhost:3306‘ (-2)

    Ich muß dazu sagen, daß ich in der my.cnf networking abgeschaltet habe, lt. Doku soll aber localhost weiter nutzbar sein.
    Habe mich jetzt mal versuchsweise ‚zu Fuß‘ eingeloggt und was lustiges gefunden:
    # mysql —host=localhost -u root -p – geht normal weiter, d.h. regulär eingeloggt.
    Mache ich aber:
    # mysql —host=localhost:3306 -u root -p – kommt – na rate mal –

    ERROR 2005 (HY000): Unknown MySQL server host ‚localhost:3306‘ (-2)

    Als Port ist bei mir 3306 eingestellt! Der Server ist 10.1.25-MariaDB.
    …grmpf….

    Meine manpage hat einen extra switch für den Port:

    -P, —port=# Port number to use for connection or 0 for default to, in order of preference, my.cnf, $MYSQL_TCP_PORT, /etc/services, built-in default (3306).

    Ich hoffe, Dir fällt dazu was ein…

    Schöne Grüße, Wolfgang

    Antworten

    1. Hallo Wolfgang,
      danke für den Hinweis. In Version 0.2.1 habe ich diesen Fehler behoben – calcardbackup beachtet nun auch in der config.php angegebene Portnummer/Socket für die Verbindung zu MySQL/MariaDB.
      Viele Grüße,
      Bernhard

      Antworten

  7. Hallo,
    erstmal tolle Sache so ein script zur Sicherung.
    Hab ich schon lange danach gesucht.

    Aber leider bekomme ich beim sichern meine Contacts immer folgenden Fehler calcardbackup:

    ERROR —
    — ERROR: the saved file is not a valid addressbook-file. Something went wrong.
    — My guess: either wrong configured URL to Nextcloud or a wrong combination of username/password in users.txt.
    — You may want to check the saved file for any hints what went wrong: /home/odroid/calcardbackup/backups/calcardbackup-2017-05-18/Fahrstunden-Contacts.vcf-ERROR.txt
    — calcardbackup: Exiting.

    in der Error Datei steht nichts und ich hab in diesem Benutzer eigentlich auch keine Kontakte.
    Danke und viele Grüße
    Andy

    Antworten

    1. Hallo Andy,
      das Problem war, dass curl >= 7.42.0 leere Dateien erzeugt, wenn es ein leeres Adressbuch empfängt. Ältere Versionen von curl erzeugen in dem Fall keine leere Datei.
      Ich habe das Skript korrigiert (v0.1.2) und kompatibel für neuere Versionen von curl gemacht.
      Danke für dein Feedback und viele Grüße,
      Bernhard

      Antworten

  8. Hallo Bernhard,
    habe gerade Dein Script ausprobiert, weil ich hier mit NC-10 auf nem Raspi rumprobiere und ich solche Sicherungen für ziemlich wichtig halte.

    Das Script zickt aber an einer Stelle, wo ich nicht so recht eingreifen möchte:

    root@raspberrypi:/usr/local/bin/calcardbackup# sudo -u www-data ./calcardbackup
    
    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    +
    + Mit Mai 10 12:06:26 CEST 2017 —> START calcardbackup
    + Checking dependencies and preparing…
    + Using configuration file /usr/local/bin/calcardbackup/calcardbackup.conf, ignoring all other command line options.
    —
    — WARNING: Configured Nextcloud-URL differs from ‚overwrite.cli.url‘ in config.php
    — http://192.168.210.12/NC10/ ==> given with option -a/—address or found in config file.
    — http://localhost/ ==> detected in /var/www/NC10/config/config.php
    — Using the latter one!
    —
    + Using URL http://localhost
    — calcardbackup: ERROR —
    — ERROR: No Own-/Nextcloud Installation found at http://localhost !
    — calcardbackup: Exiting.

    Der Nextcloud-Installer hat in der php.ini diesen localhost-Eintrag gemacht, und damit läuft auch bisher alles.
    Wenn ich in der config was anderes angebe, solle er doch dann das nehmen – oder?

    Schöne Grüße Wolfgang

    Antworten

    1. Hallo Wolfgang,
      stimmt. Es wäre besser, wenn das Skript in so einem Fall nicht abbricht, sondern die gegebene URL nimmt und nur einen Hinweis ausgibt, dass die beiden URLs nicht übereinstimmen (was auf eine Fehlkonfiguration hindeuten könnte).
      Ich habe das Skript entsprechend geändert (v0.1.1). Jetzt dürfte es nicht mehr abbrechen – zumindest nicht an dieser Stelle 😉
      Danke für dein Feedback und viele Grüße,
      Bernhard

      Antworten

  9. Hi, ich würde den Cron-Eintrag in die Crontab des Users www-data vornehmen:

    crontab -u www-data -e

    editiert automatisch die richtige Crontab.

    Antworten

Schreibe einen Kommentar zu Boris Antwort abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden.