Lubię korzystać z WordPressa z uwagi możliwość szybkiej implementacji wielu funkcjonalności za pomocą pluginów. Aby jednak czuć się pewniej przy magii jaką oferuje potrzebowałem dodatkowego poziomu bezpieczeństwa – kopii zapasowej niezależnej od aktualne używanego hostingu.

Wykorzystałem więc eksperymentalnie Github Actions do cyklicznego tworzenia kopii zapasowej plików i bazy danych. Dzięki temu w prywatnym repozytorium przechowuję historię zmian zarówno plików, jak i bazy danych. Repozytorium aktualizowane jest cyklicznie w ustalonych przeze mnie odcinkach czasu.

Roboczy, eksperymentalny Githubowy workflow przedstawia się następująco:

name: Get backup
on:
  push:
    branches:
      - master
  schedule:
    - cron: '0 4 * * 0,5'

jobs:
  backup:
    name: Backup
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@master
      - name: Libs and config
        run: |
          sudo apt-get install -y lftp
          sudo apt-get install git-ftp
          git config --local user.email "mymail@xyz.com"
          git config --local user.name "GitHub Action"
      - name: Download and commit database
        working-directory: ./database
        run: |
          export MYSQL_PWD=${{ secrets.MYSQL_PASSWORD }}
          mysqldump --column-statistics=0 -h ${{ secrets.MYSQL_HOST }} -u ${{ secrets.MYSQL_USER }} ${{ secrets.MYSQL_DBNAME }} > db.sql
          git add .
          git diff-index --quiet HEAD || git commit -a -m "Database dump $(date +"%D %T")"
      - name: Download and commit website
        run: |
          git config git-ftp.url ${{ secrets.FTP_URL }}
          git config git-ftp.user ${{ secrets.FTP_USER }}
          git config git-ftp.password ${{ secrets.FTP_PASSWORD }}
          git config git-ftp.insecure 1
          git ftp download --changed-only --no-commit
          git add .
          git diff-index --quiet HEAD || git commit -a -m "Website dump $(date +"%D %T")"
      - name: Push changes
        uses: ad-m/github-push-action@master
        with:
          github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN_GENERATE }}

Workflow uruchamiany jest:

  • za każdym razem, gdy pojawią się zmiany w branchu master
  • za pomocą cron’a: o godzinie czwartej zerowego i piątego dnia tygodnia

Job działa na ubuntu-latest wykonując kolejno:

  • Checkout Repo – zaciągnięcie plików brancha master aby były dostępne dla naszego skryptu.
  • Libs and config – instalację bibliotek lftp i git-ftp, konfigurację gita.
  • Download and commit database – zrzut bazy danych i zapisanie go do pliku za pomocą komendy mysqldump, jeżeli nowa kopia jest różna od poprzedniej, to zacommitowanie zmian.
  • Download and commit website – pobranie plików strony z serwera ftp za pomocą git-ftp, jeżeli istnieje różnica miedzy poprzednią kopią to zacommitowanie zmian.
  • Push changes – opublikowanie zmian w branchu master.

Rozwiązanie zostało zaimplementowane na szybko, z pewnością nie jest najbardziej optymalnym rozwiązaniem i najlepszym z możliwych. Zdążyło mi już jednak uratować skórę, gdy po aktualizacji jednej z wtyczek WordPress doświadczył „Technical Issue”.

Kolejne kroki które warto przeprowadzić:

  • dopracowanie skryptu
  • opublikowanie rozwiązania jako Action w Github Marketplace
  • opracowanie rozwiązania przywracającego kopię znajdującą się w repozytorium za pomocą jednego polecenia.