Migracja bloga z Wordpress do Hugo

5 lutego uruchomiłem niniejszego bloga w nowej technologii i nowej szacie graficznej. Częstotliwość wpisów była do tej pory zdecydowanie za mała. Mam nadzieję, że w tym roku się to zmieni, ponieważ mam wiele pomysłów na kolejne artykuły. Planuję pisać o rozwiązaniach problemów technicznych na bardzo różnym poziomie zaawansowania, recenzować kursy i książki branżowe oraz dzielić się przemyśleniami związanymi z organizacją procesu wytwórczego.

Ustaliłem sobie realny plan na ten rok - minimum 18 wpisów. Zobaczymy za rok czy moja estymacja okazała się trafiona :)

Teraz przyprawie pierwszy wpis kilkoma smaczkami technicznymi związanymi z migracją bloga.

Czyszczenie zawirusowanej strony

Przyznam się szczerze, że pomysł odświeżenia bloga chodził za mną od dłuższego czasu, ale zawsze znajdywały się inne pilne zadania. Sytuacja się zmieniła, gdy okazało się, że wszystkie strony (głównie postawione na wordpress), które utrzymywałem na jednym hostingu, zostały zainfekowane. Zanim jednak przeszedłem do etapu migracji bloga, podjąłem próbę wyczyszczenia zainfekowanych stron.

Niestety najstarszy backup jaki miałem zawierał już pliki ze wstrzykniętym złośliwym kodem.

Zainfekowane strony miały zmodyfikowane daty utworzenia/modyfikacji plików, aby trudniej było namierzyć nadmiarowe/zainfekowane pliki.

Zidentyfikowałem nadmiarowe pliki o nazwach, które wyglądały na wygenerowany losowy ciąg znaków np. b61pamq1.php oraz pliki PHP w katalogach, które powinny zawierać tylko statyczne pliki np. obrazki/css/javascript. Przeszukałem kod pod kątem występowania metod eval oraz base64_decode - przykładowe złośliwe fragmenty

1eval(base64_decode("VGhpcyBpcyBzYW1wbGUgbWFsd2FyZQ=="));

Udało się oczyścić kod ze złośliwych fragmentów oraz nadmiarowych plików i doprowadzić strony do działania. Po zrobieniu porządku w kodzie od razu zrobiłem również aktualizację wszystkich wordpressów.

Niestety, po jakimś czasie znowu pojawiły się złośliwe pliki i fragmenty wstrzykniętego kodu. Prawdopodobnie wtyczka w jednym z wordpressów miała dziurę. Shared hosting nie pozwalał wyizolować działania poszczególnych stron, więc podatność na jednej z nich infekowała pozostałe.

Backup statycznej strony

W planach miałem aktualizację bloga. Wiedziałem, że zanim zmigruję bloga na nowe rozwiązanie minie trochę czasu. Potrzebowałem zrobić zrzut statycznej wersji mojego starego bloga, a następnie podmienić tego, który obecnie działał na wordpress.
Poszukiwania odpowiedniego narzędzia naprowadziły mnie na httrack. Strona informacyjna tego narzędzia wydawała się lekko archaiczna - ostatni release odbył się 05/20/2017. Dodatkowo ilość opcji była przytłaczająca. Jednak po kilku próbach użycia okazało się, że samo polecenie do wykonania statycznej kopii strony jest banalne.

1httrack "https://mariusz.wyszomierski.pl" -O "/home/speedlog/mariusz.wyszomierski.pl" +*.*

Jednym z mankamentów było to, że narzędzie nie obsługiwało pobrania obrazków z atrybutu srcset.

1<img src="wp-content/uploads/2016/09/Wildfly_logo.jpg"
2     srcset="https://mariusz.wyszomierski.pl/wp-content/uploads/2016/09/Wildfly_logo.jpg 600w, https://mariusz.wyszomierski.pl/wp-content/uploads/2016/09/Wildfly_logo-300x90.jpg 300w">

Po przejściu na statyczną wersję strony przestały działać wszystkie "dynamiczne" funkcjonalności wymagające komunikacji ze skryptami PHP typu "formularz kontaktowy" czy wyszukiwarka. Mimo powyższych niedoskonałości rozwiązanie spełniało zasadę good enough.

Wybór nowego oprogramowania dla bloga

Do tej pory jako framework używałem Wordpressa. Z uwagi na faktyczne potrzeby bloga, było to jak strzelanie z armaty do muchy. Wtedy jednak rozwiązanie wydało mi się optymalne ze względu na szybkość uruchomienia i łatwe zarządzanie. Na przestrzeni ostatnich lat powstał nowy trend tworzenia stron - generatory statycznych stron. Idea jest całkiem prosta - na podstawie plików konfiguracyjnych, szablonu i przygotowanych przez nas treści generowana jest strona w postaci statycznych plików HTML/CSS/JS. To rozwiązanie ma wiele zalet:

  1. Wysokie bezpieczeństwo rozwiązania. Jedyny atak na tak przygotowaną stronę to włamanie się bezpośrednio na serwer.
  2. Wysoka skalowalność. Z uwagi na to, że strona to po prostu statyczne pliki, może być cachowana nawet w całości w pamięci lub dostarczana za pomocą CDN1.
  3. Tania infrastruktura. Do działania wymaga po prostu serwera HTTP zwracającego pliki statyczne.
  4. Łatwy backup. W przypadku statycznej strony wystarczy zrobić backup plików - w przeciwieństwie do Wordpress, gdzie konieczny był dodatkowo backup bazy danych. Wygenerowane pliki mogą być wersjonowane w repozytorium git i tym samym być backupem.

Istnieją również ograniczenia tego rozwiązania:

  1. Brak CMS2 do zarządzania stroną i tworzenia treści. Wymagana jest nieco większa wiedza niż ta, którą posiada zwykły użytkownik internetu.
  2. Brak dynamicznych funkcjonalności np. formularzy kontaktowych, mechanizmu komentarzy, obsługi logowania użytkowników.
Zewnętrzne rozwiązania dla systemu komentarzy

Można dodać do strony pliki javascript obsługujące komunikację z własnym lub zewnętrznym API obsługującym takie dynamiczne funkcjonalności np w przypadku komentarzy:

Powyższe ograniczenia jednak nie są kluczowe z punktu widzenia mojego bloga.

Istnieje wiele różnych generatorów stron statycznych - tu mogę polecić stronę, która agreguje różne rozwiązania oraz pokazuje statystki z githuba, dzięki którym można ocenić dojrzałość i aktywność projektu jamstack.org/generators/.

Mój wybór padł na Hugo z uwagi na bardzo czytelną dokumentację, dojrzałość projektu oraz dobrą bazę gotowych szablonów.

Przenoszenie treści wpisów

Wpisy w Hugo używają formatu markdown. Na moje szczęście nie zrobiłem zbyt wiele wpisów na starym blogu, ale część z nich była w dwóch językach, więc to dołożyło pracy. Przy przenoszeniu wpisów przydatnym narzędziem okazał się konwerter skopiowanego fragmentu strony do formatu markdown - euangoddard.github.io

Konwersja obrazków

Część obrazków na dotychczasowym blogu była zapisana jako PNG. Postanowiłem przy okazji migracji skonwertować obrazki do formatu JPEG, aby strona szybciej się ładowała. Konieczne było również przeskalowanie miniaturek wpisów. Wykonanie tych operacji np. w GIMP wydało mi się malo efektywne, więc znalazłem sposób na wykonanie tych operacji z linii poleceń.

Poniższe polecenie zmienia wszystkie obrazki PNG:

  • skaluje obrazek do maksymalnej szerokości/wysokości 150px
  • zmienia format na JPG
  • ustawia kompresje na 70%
1mogrify -resize 150x150 -format jpg *.png

  1. Cloudflare - what is JAMSTACK? ↩︎

  2. Dotyczy większości rozwiązań generatorów. Istnieją już takie generatory, które uruchamiają lokalnie prosty edytor WYSWIG do zarządzania treścią statycznej strony: netlifycms.org ↩︎