Normale Ansicht

Es gibt neue verfügbare Artikel. Klicken Sie, um die Seite zu aktualisieren.
Ältere BeiträgeHaupt-Feeds

Mein Paperless-NGX-Mini-Konzept

31. Juli 2023 um 05:00

Paperless-NGX ist ein bekanntes und beliebtes Open Source Dokumenten-Management-System (DMS). Auch ich möchte zukünftig meinen „Papierkram“ darin verwalten.

In diesem Artikel halte ich meine Gedanken fest, wie ich plane, paperless-ngx in meiner Umgebung aufzusetzen und zu betreiben.

Dies hilft mir, zu prüfen, ob ich auch an alles Wichtige gedacht habe. Falls euch das Konzept gefällt, dürft ihr es selbstverständlich gerne nachahmen. Und wenn ihr schwerwiegende Fehler darin entdeckt, freue ich mich über einen Hinweis.

Es ist kein Tutorial und keine Schritt-für-Schritt-Anleitung. Zwar mag dieser Text dazu dienen, sich eine eigene Umgebung aufzubauen, Mitdenken ist dabei jedoch zwingend erforderlich.

Ziele

  • Betrieb von Paperless-NGX als rootless-Podman-Container
  • Consumption-Ordner als Samba-Share freigegeben, um via Netzwerk Dateien hineinkopieren zu können
  • Getrennte Benutzerkonten für meine Frau und mich
  • Freigabe gewisser Dokumente für weitere Benutzer(gruppen)
  • Erfolgreicher Restore-Test

Infrastruktur

In meinem Heimnetzwerk betreibe ich einen Desktop-/Server-PC. Auf diesem läuft aktuell RHEL 9 als KVM/QEMU-Hypervisor. Er dient mir ebenfalls als Ansible Control Node. Hierauf betreibe ich eine RHEL-9-VM mit einer rootless-Podman-Installation. Diese VM wird auch meine Paperless-NGX-Instanz hosten.

In der VM wird das EPEL-Repository aktiviert, um daraus die Pakete podman-compose und python3-pexpect installieren zu können.

Falls ich mal nicht mehr weiß, wie dieses Setup aufgebaut wird, finden sich dazu Hinweise in folgenden Links:

Installation mit Ansible

Für die Installation der Anwendung wird die Container Route verwendet. Die Installation wird dabei unter Nutzung der Ansible-Rolle tronde.paperless_ngx_with_rootless_podman automatisiert.

Das Playbook deploy_paperless_ngx.yml, welches auf meiner Synology Diskstation abgelegt ist, führt die Installation und Konfiguration der Anwendung durch. Es installiert und konfiguriert zudem Samba und die Datei-Freigabe des Consumption-Verzeichnisses.

In dem Playbook werden folgende Rollen verwendet:

Die Rollen sind mit dem Playbook in meinem Ansible-Projekt-Verzeichnis auf meiner Synology Diskstation installiert.

Alle Playbooks und Rollen werden mit Git versioniert. Die Repositories werden auf entfernte Rechner synchronisiert.

Vorbereitung

Die Dateien docker-compose.postgres-tika.yml, docker-compose.env und .env werden aus dem Projekt-Repository in das Rollen-Verzeichnis files meiner Ansible-Rolle heruntergeladen. Die Datei docker-compose.postgres-tika.yml wird dabei zu docker-compose.yml umbenannt und bearbeitet.

Um Datenverlust vorzubeugen, wird die Ansible-Rolle mit den angepassten Dateien in die regelmäßige Datensicherung aufgenommen.

Folgende Variablen werden in meinem Ansible-Vault hinterlegt:

# Paperless-ngx with podman-compose
pnwrp_podman_user: alice
pnwrp_podman_group: alice
pnwrp_compose_dir: /home/{{ pnwrp_podman_user }}/paperless-ngx
pnwrp_paperless_superuser: alice
pnwrp_paperless_superuser_email: alice@example.com
pnwrp_paperless_superuser_password: ImWunderland
## Username and password for document scanner
brother_scanner_user: scanner
brother_scanner_pass: ImWunderland

Die Werte der Variablen werden selbstverständlich angepasst.

Das Playbook

Folgender Code-Block zeigt das fertige Playbook mit Beispielwerten:

---
- hosts: host.example.com
  remote_user: alice
  debugger: never
  vars_files:
    - files/alice.vault
  tasks:
    - name: Setup Paperless-NGX with podman-compose in rootless Podman
      include_role:
        name: ansible_role_paperless-ngx_with_rootless_podman

    - name: Enable Port 8000/tcp in host firewall
      ansible.posix.firewalld:
        port: 8000/tcp
        immediate: true
        permanent: true
        state: enabled
      become: true

    - name: >-
        Create and add {{ brother_scanner_user }} to
        {{ pnwrp_podman_group }}
      ansible.builtin.user:
        name: "{{ brother_scanner_user }}"
        comment: "Brother Dokumenten-Scanner"
        create_home: false
        groups: "{{ pnwrp_podman_group }}"
        append: true
        shell: /usr/sbin/nologin
        state: present
        system: true
      become: true

    - name: Include role vladgh.samba.server
      include_role:
        name: vladgh.samba.server
      vars:
        ansible_become: true
        samba_users:
          - name: "{{ pnwrp_podman_user }}"
            password: "{{ alice_password }}"
          - name: "{{ brother_scanner_user }}"
            password: "{{ brother_scanner_pass }}"
        samba_shares:
          - name: consumption
            comment: 'paperless consumption directory'
            path: "{{ pnwrp_compose_dir }}/consume"
            read_only: false
            guest_ok: false
            browseable: true
            owner: "{{ pnwrp_podman_user }}"
            group: "{{ pnwrp_podman_group }}"
            write_list: +{{ pnwrp_podman_group }}

    - name: Enable samba in host firewall
      ansible.posix.firewalld:
        service: samba
        immediate: true
        permanent: true
        state: enabled
      become: true

Das Playbook gewinnt sicher keinen Schönheitswettbewerb, doch arbeitet es bisher robust und tut, was es soll. In Tests habe ich meine Wunschumgebung damit mehrmals provisioniert.

Backup & Restore

Wie es sich gehört, wird erst ein Backup erstellt, dann die Anwendung inkl. aller Daten gelöscht und wiederhergestellt.

Backup

Für das Backup verwende ich ein Ansible-Playbook, welches sich zum Podman-Host verbindet und dort folgende Aufgaben ausführt:

  1. Stelle sicher, dass das Backup-Verzeichnis auf dem Remote-Host existiert
  2. Stoppe alle Paperless-NGX-Container
  3. Exportiere Podman-Volumes in TAR-Archive; hänge das aktuelle Datum an die Dateinamen an
  4. Archiviere und komprimiere paperless-ngx-Verzeichnis auf Remote-Host; hänge das aktuelle Datum an die Dateinamen an
  5. Starte alle Paperless-NGX-Container
  6. Komprimiere die Exporte der Podman-Volumes
  7. Synchronisiere das Backup-Verzeichnis auf dem Remote-Host mit einem Verzeichnis auf meiner Diskstation
  8. Synchronisiere das Diskstation-Verzeichnis mit einem verschlüsselten S3-Bucket

Es fehlt die Aufgabe, alte Backups aufzuräumen. Darum werde ich mich kümmern, wenn 70% des verfügbaren Speicherplatzes belegt sind.

Der folgende Code-Block zeigt ein Muster des verwendeten Playbooks:

---
- name: Backup podman volumes
  hosts: host.example.com
  gather_facts: true
  vars:
    paperless_ngx_dir: /home/alice/paperless-ngx
    docker_compose_file: docker-compose.yml
    remote_backup_dir: /home/alice/backups
    diskstation_backup_dir: /home/alice/diskstation/home/backups/host.example.com

  tasks:
    - name: Ensure backup directory exists
      ansible.builtin.file:
        path: "{{ remote_backup_dir }}"
        state: directory
        owner: alice
        group: alice
        mode: 0777

    - name: Stop paperless-ngx containers
      ansible.builtin.command: >
        podman-compose -f {{ paperless_ngx_dir }}/{{ docker_compose_file }} stop

    - name: List podman volumes
      ansible.builtin.command: podman volume ls --quiet
      register: __podman_volumes
      tags:
        - volumes

    - name: Output __podman_volumes
      ansible.builtin.debug:
        msg: "{{ item }}"
      loop: "{{ __podman_volumes['stdout_lines'] }}"
      tags:
        - volumes

    - name: Export podman volumes
      ansible.builtin.command: >
        podman volume export {{ item }} --output {{ remote_backup_dir }}/{{ item }}_{{ ansible_facts['date_time']['date'] }}.tar
      loop: "{{ __podman_volumes['stdout_lines'] }}"

    - name: Compact {{ paperless_ngx_dir }}
      community.general.archive:
        path: "{{ paperless_ngx_dir }}"
        dest: "{{ remote_backup_dir }}/paperless-ngx_{{ ansible_facts['date_time']['date'] }}.tar.gz"
        format: gz

    - name: Start paperless-ngx containers
      ansible.builtin.command: >
        podman-compose -f {{ paperless_ngx_dir }}/{{ docker_compose_file }} start

    - name: Compress volume exports
      community.general.archive:
        path: "{{ remote_backup_dir }}/{{ item }}_{{ ansible_facts['date_time']['date'] }}.tar"
        format: gz
        remove: true
      loop: "{{ __podman_volumes['stdout_lines'] }}"
      tags:
        - compress

    - name: Sync backups to diskstation
      ansible.posix.synchronize:
        archive: true
        compress: false
        delete: false
        dest: "{{ diskstation_backup_dir }}"
        mode: pull
        private_key: /home/alice/.ssh/ansible_id_rsa
        src: "{{ remote_backup_dir }}/"
      delegate_to: localhost
      tags:
        - rsync

    - name: Sync backups from diskstation to contabo S3
      ansible.builtin.command: rclone sync -P ../backups/ secure:backups
      delegate_to: localhost
      tags:
        - rsync

Das Playbook wird einmal wöchentlich ausgeführt. Ob ich für die geplante Ausführung cron oder systemd timer units verwende, habe ich noch nicht entschieden. Ich tendiere aus Neugier zu letzterem.

Um ein Offsite-Backup zu haben, werden die Dateien von der Diskstation einmal wöchentlich verschlüsselt und in einen S3-Speicher synchronisiert. Ich nutze dafür das Programm rclone und S3-kompatiblen Speicher von Contabo. Die folgenden Links bieten weiterführende Informationen dazu:

Restore

Der Ablaufplan für die Wiederherstellung der Anwendung mit ihren Daten sieht wie folgt aus:

  1. Eine rootless-Podman-Umgebung bereitstellen
  2. podman-compose bereitstellen
  3. TAR-Archive auf Zielsystem übertragen
  4. Paperless-NGX mit Playbook installieren
  5. Alle Container stoppen
  6. Inhalt der TAR-Archive in die Podman-Volumes importieren (siehe podman-volume-import(1)): gunzip -c hello.tar.gz | podman volume import myvol -
  7. Alle Container starten

Fazit

Bereitstellung, Sicherung und Wiederherstellung funktionieren wie beschrieben. Damit kann ich nun beginnen und die Anwendung konfigurieren und mit meinem Papierkram füttern.

Die Samba-Freigabe habe ich ebenfalls getestet. Sie funktioniert wie erwartet. PDF-Dateien mit dem Befehl find Documents -type f -iname "*.pdf" -exec cp {} /consume \; hineinzukopieren ist übrigens besonders dann eine gute Idee, wenn man sehen möchte, welche Dateien so in den Tiefen des eigenen Dateisystems schlummern.

SystemRescueCd 9.04 – ab sofort mit rclone

Von: jdo
09. August 2022 um 07:27

Fast zeitgleich mit dem auf Ubuntu-basierenden Rescuezilla 2.4 ist eine neue Version von SystemRescueCd erschienen, das auf Arch Linux basiert. Ab sofort kannst Du die vierte Wartungs-Version, SystemRescueCd 9.04, herunterladen. Ab sofort wird die Architektur i686 übrigens nicht mehr unterstützt. Die letzte Version für diese Plattform ist 9.03, es sei denn, es finden sich Freiwillige, die diese Architektur weiterhin pflegen. Der Linux-Kernel wurde auf 5.15.58 LTS aktualisiert. Zudem wurde ein Fehler bei DNS während der initramfs-Startphase ausgebessert. Die Konfigurationsoption ca-trust […]

Der Beitrag SystemRescueCd 9.04 – ab sofort mit rclone ist von bitblokes.de.

❌
❌