Das Nextcloud Notfall Playbook

Nextcloud ist ein wichtiger Teil meiner Datenhaltung. Daher habe ich mir überlegt, wie ich im absoluten Notfall das System möglichst schnell wieder ans Laufen bekomme. Dazu brauche ich ein Notfall Playbook, das mir den Raspberry Pi komplett einrichtet und die Dockercontainer baut.

raspithek.de - Olli Graf
nc-logoCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=

Szenario

Das Szenario besteht aus der Annahme, dass nach einem Hardwareversagen die Nextcloud Installation komplett neu aufgesetzt werden muss. Dies lässt sich mit einem Ansible Playbook sehr gut automatisieren. Dazu zerlegen wir den Einrichtungsprozess in mehrere einzelne Schritte, für die wir einzelne Plays bauen.

Rolle anlegen

Zunächst benötigen wir ein Verzeichnis für unsere Rolle mit den Unterverzeichnissen.

mkdir -p roles/initnextcloud/tasks
mkdir -p roles/initnextcloud/files
mkdir -p roles/initnextcloud/vars

Parametrisierung

Zunächst müssen wir uns überlegen, welche Werte sich bei einer Neuinstallation von der alten Installation unterscheiden können. Diese lagern wir in Variablendeklarationen in einzelne Dateien aus und deklarieren Variablen darin.

Als erstes fällt mir da die PARTUUID der Daten NVME ein, die sich beim Austausch des Datenträgers ändern kann.

Diese deklarieren wir in roles/initnextcloud/vars/partuuid.yml

partuuid: "011ad286-01"

Die PARTUUID kannst du mit

ls -l /dev/disk/by-partuuid/

oder alternativ mit

blkid /dev/sda1

herausfinden. Du musst dazu die Partition deines Datenträgers nehmen.

raspithek.de - Olli Graf
discover-partuuidCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
PARTUUID mit ls herausfinden.

Auf meinem Testsystem für diesen Post simuliert ein USB-Stick den NVME-Datenträger des produktiven Systems. Die Partition darauf ist unter /dev/sda1 gelistet.

Die Variablendatei roles/initnextcloud/vars/pckg.yml enthält alle Packages, die mit apt auf dem neu aufgesetzten System installiert werden sollen. Diese kannst du nach Belieben anpassen.

packages:
  - python3-docker
  - neofetch
  - htop
  - cowsay
  - docker.io
  - docker-compose
  - git
  - locate
  - dnsutils
  - nfs-kernel-server
  - vim
  - lsof
  - ripgrep

Die Paketliste solltest du für dein System pflegen und aktualisieren.

Die Nextcloud Installation benötigt einige Verzeichnisse u.a. für die Volumes der Container. Auch die deklarieren wir in einer Liste in roles/initnextcloud/vars/dirs.yml

Zusätzlich deklarieren wir hier den URL für das Docker Repository und das Verzeichnis, in das das Repo hinein gecloned werden soll.

dockerrepo: "https://raspithekgit.srv64.de/raspithek/docker"
dockerdir: "/home/pi/git/dockercmd"

volumedirs:
  - /mnt/nextcloud
  - /opt/clamav

homedirs:
  - bin
  - git

ncdirs:
  - /mnt/nextcloud/nextcloud/apps
  - /mnt/nextcloud/nextcloud/html
  - /mnt/nextcloud/nextcloud//data
  - /mnt/nextcloud/nextcloud/config



Mit diesen drei .yml Dateien ist die Konfiguration unseres Playbooks bereits abgeschlossen.

Installationsschritte

Jetzt überlegen wir, was wir machen müssen, um Nextcloud im Notfall wieder ans Laufen zu bekommen.

Voraussetzung ist ein bootfähiges System, bei dem der ssh Zugang mit private Key für den User pi möglich ist.

Ich zerlege die Aufsetzprozedur in diese Teilschritte

  1. Einrichten des Betriebssystems
  2. Daten-NVME mounten und in fstab anlegen
  3. Anlegen der benötigten Verzeichnisse
  4. Docker Container einrichten
  5. zusätzliche optionale Schritte

Einrichten des Betriebssystems

Hier wird in erster Linie ein dist-upgrade von Raspberry Pi OS durchgeführt, im zweiten Schritt werden die Pakete aus der oben deklarierten Liste installiert.

- name: PI Update
  become: true
  apt:
    update_cache: yes
    upgrade: dist
- name: Pakete installieren
  become: true
  ansible.builtin.apt:
    name: "{{ packages }}"
    state: present
    update_cache: yes
    cache_valid_time: 86400

Datenpartition mounten

Zum Mounten der Datenpartition muss der notwendige Mountpoint angelegt werden. Danach wird ein Backup der /etc/fstab erzeugt. Das Mounten der der Partition fügt automatisch einen neuen Eintrag in der fstab hinzu. Danach ist die Partition verfügbar und wird auch nach einem Neustart wieder eingebunden. Da Ansible die Facts nicht von sich aus aktualisiert, müssen wir das explizit anstoßen.

- name: create mount dir
  become: true
  file:
    path: "/mnt/nextcloud"
    state: directory

- name: Backup der /etc/fstab anlegen
  become: true
  ansible.builtin.copy:
    src: /etc/fstab
    dest: /etc/fstab.backup.{{ ansible_date_time.iso8601 }}
    remote_src: yes
    mode: '0644'


- name: Ensure /mnt/nextcloud is mounted and in fstab
  become: true
  ansible.posix.mount:
    path: /mnt/nextcloud
    src: "PARTUUID={{ partuuid }}"
    fstype: "ext4"
    opts: "defaults,noatime"
    state: mounted

- name: Facts aktualisieren
  setup:
    filter: ansible_mounts

Anlegen der benötigten Verzeichnisse

Dieses Play arbeitet die drei Listen aus vars/dirs.yml ab und legt die Verzeichnisse an. Als erstes wird geprüft, ob die Datenpartition korrekt eingebunden ist, sonst hat ein Weiterleiten des Playbooks keinen Zweck und es wird mit Fehlermeldung abgebrochen.

- name: Abbrechen, wenn /mnt/nextcloud nicht gemountet ist
  fail:
    msg: "/mnt/nextcloud ist nicht gemountet – Playbook wird abgebrochen."
  when: "'/mnt/nextcloud' not in (ansible_mounts | map(attribute='mount') | list)"
- name: create home dirs
  file:
    path: "~/{{ item }}"
    state: directory
  loop: "{{ homedirs }}"

- name: create volume dir
  become: true
  file:
    path: "{{ item }}"
    state: directory
    owner: pi
    group: pi
    mode: '0755'
  loop: "{{ volumedirs  }}"

- name: create nextcloud dirs
  file:
    path: ~/{{ item}}
    state: directory
  loop: "{{ ncdirs  }}"

Dockercontainer einrichten

Dieser Schritt cloned das Docker Repository mit dem notwendigen docker-compose.yml und fügt den User pi den benötigten Gruppen hinzu. Dann werden alle Container im docker-compose.yml erzeugt und gestartet. Dieser Schritt darf natürlich erst nach dem Anlegen der Verzeichnisse für die Volumes geschehen!

- name: Clone docker-compose repository
  ansible.builtin.git:
    repo: "{{ dockerrepo }}"
    dest: "{{ dockerdir }}"
    version: master

- name: Permission für Docker
  become: true
  file: path=/var/run/docker.sock mode=0660
#    mode: 660

- name: adding user pi to docker group
  become: true
  user:
    name: pi
    groups: docker,video


- name: Run docker-compose up
  community.docker.docker_compose:
    project_src: '{{dockerdir }}/nextcloud'
    state: present
  become: true

Optionale Aufgaben

Dieser Schritt hat weniger mit Nextcloud zu tun sondern dient mehr, mir die Bedienung des Systems zu vereinfachen. zum einen kopiere ich hier meine Scripts auf den Pi, zum anderen benötigte Dateien für den User. Du kannst ihn gerne benutzen, aber auch völlig weglassen. Beide Tasks benutzen die fileglob Schleife, um alle Dateien unter roles/initnextcloud/files/scripts nach /home/pi/bin zu kopieren.Genauso wird alles unter roles/initnextcloud/files/resources ins Homeverzeichnis von pi kopiert.

- name: copy scripts
  copy:
    src: "{{ item }}"
    dest: /home/pi/bin
    mode: '0755'
  loop: "{{ query('fileglob', 'files/scripts/*') }}"

- name: copy resources to ~
  copy:
    src: "{{ item }}"
    dest: /home/pi
  loop: "{{ query('fileglob', 'resources/*') }}"

main.yml

Alle diese einzelnen Plays können wir jetzt in der main.yml einbinden.

- include_vars: "roles/initnextcloud/vars/dirs.yml"
- include_vars: "roles/initnextcloud/vars/partuuid.yml"
- include_vars: "roles/initnextcloud/vars/pckg.yml"
- import_tasks: install.yml
- import_tasks: optional.yml
- import_tasks: mount.yml
- import_tasks: dirs.yml
- import_tasks: docker.yml

Zunächst müssen alle Variablendeklarationen inkludiert werden, danach die Task Files in der Reihenfolge, wie sie abgearbeitet werden sollen. In der Reihenfolge ist in erster Linie wichtig:

  1. Das Datenlaufwerk ist gemounted bevor die Volume Verzeichnisse angelegt werden, da sie zum Teil auf dem Laufwerk liegen
  2. Die Verzeichnisse müssen vor dem Start der Dockercontainer existieren.

Das Playbook

Das Playbook ist ziemlich kurz, da die gesamte Logik in der Rolle liegt. Beachte, dass hier gather_facts explizit eingeschaltet ist, da dirs.yml sonst den Zustand der Datenpartition nicht abfragen kann.

---
- hosts: "{{ target }}"
  gather_facts: true
  remote_user: pi
  roles:
    - initnextcloud

Test

Zum Test des Playbooks benutze ich einen Raspberry Pi 5 16GB mit angesteckten 64GB USB Stick. Dieser soll die Daten NVME des produktiven Systems simulieren.

Auf der MicroSD flashe ich eine frische Raspberry Pi OS (bookworm) Installation. Nachdem ich den ssh Zugang hergestellt habe, starte ich das Playbook

ansible-playbook -e="target=testsystem" initnextcloud.yml
erfolgreicher Lauf des Playbooks
raspithek.de - Olli Graf
playbook-runCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
erfolgreicher Lauf des Playbooks

Nach dem erfolgreichen Durchlauf logge ich mich ins System ein und prüfe, ob folgende Konfigurationen erfolgreich durchgeführt wurden:

  • Für die Datenpartition wurde ein Eintrag in der fstab angelegt
  • Für die Datenpartition wurde ein Eintrag in der /etc/fstab angelegt
  • Die Dockercontainer wurden erfolgreich gestartet.
Alle Testkriterien sind erfüllt.
raspithek.de - Olli Graf
testsCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
Alle Testkriterien sind erfüllt.

Auch nach einem Neustart ist das Setup korrekt.

Was das Playbook kann

Das Playbook stellt die komplette Nextcloud Installation auf einem fertig konfigurierten Raspberry Pi mit einem frischen Raspberry Pi OS her. Die Container von ClamAV und Nextcloud Cron werden dabei über das docker-compose.yml mit aufgebaut.

Was das Playbook nicht kann

Backupdaten einspielen und Nextcloud konfigurieren. Auch die Anbindung an ClamAV muss du manuell herstellen.

Fazit

Dieses Notfall Playbook stellt die Installation von Nextcloud innerhalb von wenigen Minuten wieder her. Was es allerdings nicht kann, ist die verwalteten Daten wiederherzustellen. Dafür braucht es einen separaten Mechanismus.

Das Playbook ist speziell für mein persönliches Setup angepasst. Ich habe mich aber bemüht, es so weit konfigurierbar zu machen, dass du es für deinen eigenen Nextcloud Server verwenden kann.

Das gesamte Playbook mit allen Dateien habe ich im git Repository abgelegt.

Schreibe einen Kommentar

Insert math as
Block
Inline
Additional settings
Formula color
Text color
#333333
Type math using LaTeX
Preview
\({}\)
Nothing to preview
Insert
Creative Commons License
Except where otherwise noted, the content on this site is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
raspithek.de - Olli Graf
WordPress Cookie Hinweis von Real Cookie Banner