Contao mit Ansible verwalten - Teil 5

von Kirsten Roschanski

Vollbackup von Contao

Grundlage

Die Grundsteine sind bereits gelegt. Auf dieser Basis setze ich heute und zeige wie man die Installation zentral sichern kann.

Information

Ich habe lange diskutiert und sicherlich kann und will jemand anderes noch ganz andere Teile sichern. Daher zeige ich heute auch, wie du weitere Teile hinzufügst. Da ich die Installation auch per Ansible aufgesetzt habe und daher viele Teile bereits lokal liegen habe, sichere ich dieses mal nur die Basis.

Vorbereitung

In meine Struktur füge ich nun das neue Playbook ein. Damit sieht meine Struktur nun wie folgt aus:

contao-ansible // Verzeichnis für Ansible-Playbooks
  customers // Verzeichnis für Installationen
    kirsten-roschanski.de.yml // Konfig meiner Webseite
  templates // Verzeichnis für Templates 
    composer.j2
    contao-manager-config.j2
    contao-manager-user.j2
    localconfig.php.j2
    parameters.sh.j2
  backups // Verzeichnis für Datenbankbackups   
  ansible.cfg
  backup_full.yml
  update_base.yml
  install_base.yml
  datenbank_backup.yml
  upgrade_base.yml

backup_full.yml

---
- hosts: all
  tasks:
    - name: Dump of Databse
      shell: "mysqldump -u {{ database_user }} --password={{ database_password }} -h {{ database_host }} {{ database_name }} > {{ websitePath }}/system/tmp/dump.sql"
      args:
        chdir: "{{ websitePath }}"

    - name: Copy from remote to local
      ansible.builtin.fetch:
        src: "{{ websitePath }}/system/tmp/dump.sql"
        dest: "./backups/{{ inventory_hostname }}/{{ ansible_date_time.date }}-{{ inventory_hostname }}.sql"
        flat: yes

    - name: Synchronization files
      shell: "rsync -az {{ ansible_user }}@{{ inventory_hostname }}:{{ websitePath }}/files --exclude='.git' ./backups/{{ inventory_hostname }}/ "
      delegate_to: localhost

    - name: Synchronization templates
      shell: "rsync -az {{ ansible_user }}@{{ inventory_hostname }}:{{ websitePath }}/templates --exclude='.git' ./backups/{{ inventory_hostname }}/ "
      delegate_to: localhost

Was macht dieses Playbook?

Es werden folgende 4 Tasks abgearbeitet:

  1. Es wird ein Datenbankbackup in system/tmp erstellt.
  2. Der Datenbankdump wird auf die lokale Festplatte kopiert.
  3. Holt den Ordner files auf die lokale Festplatte.
  4. Holt den Ordner templates auf die lokale Festplatte.
Information

Anders als beim Playbook zum Datenbankbackup, wird jetzt ein Unterverzeichnis angelegt in dem die Dateien dann abgelegt werden.

{{ inventory_hostname }}

Diese Variable wird durch dem Host-Name aus der Konfiguration ersetzt.

Wie passe ich das Backup für meine Dateien an?

Das ist gar nicht so schwer, am besten ist wenn du dazu dir dann dann eigenes Playbook auf Basis dieses Playbooks baust.

Danach fügst du einfach weitere Tasks hinzu.

Hier mal ein Beispiel um die htaccess-Datei aus dem Ordner Web zu sichern.

- name: Copy from remote to local
ansible.builtin.fetch:
src: "{{ websitePath }}/web.htaccess"
dest: "./backups/{{ inventory_hostname }}/web/.htaccess"
flat: yes

Über Twitter haben viele auch geschrieben, das sie die lokalen Anpassungen sichern möchten, daher hier auch mal[nbsp] ein Beispiel dafür.

- name: Synchronization templates
shell: "rsync -az {{ ansible_user }}@{{ inventory_hostname }}:{{ websitePath }}/scr --exclude='.git' ./backups/{{ inventory_hostname }}/ "
delegate_to: localhost

Dieses kannst du für deine Installationen beliebig weit anpassen.

Wie führe ich das nun aus?

Wenn ich nur eine Installation sichern möchte, dann nutze ich folgenden Befehl:

ansible-playbook -i customers/kirsten-roschanski.de.yml backup_full.yml

dieses kann ich nur machen, da mein SSH-Key auf dem Server hinterlegt ist. Wenn ich das Passwort eingeben muss, dann rufe ich das mit der Option -k auf:

ansible-playbook -i customers/kirsten-roschanski.de.yml -k backup_full.yml

Da ich aber mehre Installationen mit einem mal sichern möchte, lasse ich die Angabe für die Installation weg:

ansible-playbook backup_full.yml

Das geht nur weil wir in der ansible.cfg den Ordner angegeben haben. Wenn man nun verschiedene Kundengruppen macht, dann kann mit -i Ordnername auch diese Gruppe angesprochen werden.

Tipp

Auf einem immer laufenden Rechner oder Server (bei mir ein Raspberry Pi) der nur für die Sicherung verantwortlich ist, und der zudem an das NAS angebunden ist, führe ich das Playbook per Cron Job jede Nacht um 3 Uhr aus

0 3 * * * /bin/bash -e "cd DIR [&][&] ansible-playbook backup_full.yml"

Dadurch habe ich jeden Tag ein Backup bevor die Kunden wieder Änderungen vornehmen. Dateien in files und templates werden zwar ersetzt aber nicht gelöscht, das reicht mir in der Regel. Im Notfall habe ich auf dem NAS auch noch mal 14 Tage die Dateien in den verschiedenen Versionen als Snapshoot liegen.
Ansonsten kann man natürlich den rsync auch noch anpassen um auch dieses Verhalten zu verändern, was aber für mich bisher noch nicht interessant war.

Wie geht es weiter?

Im nächsten Teil werde ich zeigen, wie man alle Konfigurationen neu schreibt und wie diese bereits erweitert wurden. z.B. um die Bildgrößen oder den wegfall der .html Endung. Danach werde ich die erste voll automatische Installation zeigen.

Projektdateien

Wer sich das nicht kopieren möchte kann auch gerne das GitRepro nutzen. Änderungen, Ideen und auch Feedback sind jederzeit gerne willkommen.