Tutaj znajduje się kod, o którym jest artykuł .
Wstęp i założenia
Nie raz dostajemy propozycję przejęcia kodu po kimś z zewnątrz i dalsze utrzymanie takiego kodu. We wpisie założę pewne z góry ustalone rzeczy, takie jak:
- klient ma serwer, jednak nie podoba mu się i chce przenieść aplikację na coś innego. Zgadza się, by całą obsługą na poziomie serwera zajęliśmy się my,
- posiadamy serwer dedykowany z dostępem do konsoli i prawami roota,
- nie mamy dostępu do repozytorium, na którym znajduje się aktualnie kod więc założymy swoje,
- użyjemy Docksala, oprogramowania dla developerów opartego o Docker i Docker Compose wspomagające lokalną pracę na kodzie,
- aplikację wgrywamy bezpośrednio na serwer produkcyjny, nie mamy serwerów pośrednich do testowania pomiędzy.
Wpis oprę o przeniesienie tego bloga, który został wrzucony przez FTP na metodę, która będzie polegała na dynamicznym deploymencie.
Stack serwera oparłem o oprogramowanie instalowane razem z https://vestacp.com/ więc ścieżki na serwerze, które niżej pokażę będą odnosiły się bezpośrednio do ścieżek jakie są generowane dla użytkowników w standardowych konfiguracjach tego panelu.
W momencie pisania tego artykułu oprogramowanie, które instalujemy na debianie zawiera PHP w wersji 5.6. Zalecam doinstalowanie PHP 7.x, wtedy z poziomu panelu vesta jesteśmy w stanie dla danego użytkownika przełączyć wersję PHP. Jak to zrobić znajdziemy tutaj: https://forum.vestacp.com/viewtopic.php?f=41&t=17129
Pamiętajmy, że nie zawsze możemy przełączyć naszej wersji PHP ze względu na kod aplikacji i funkcje, które mogą być niekompatybilne. Wspomnę o tym, że budowanie aplikacji powinno opierać się o testy, jednak nie pokażę w tym wpisie jak to zrobić.
Wirtualizacja środowiska programistycznego
Jak wspomniałem w założeniach, naszym lokalnym środowiskiem będzie Docksal. Jest to oprogramowanie, które zintegruje nam Docker i Docker Compose, a także wiele innych narzędzi ułatwiających i wspierających proces programowania. Więcej informacji z opisem narzędzi i o tym jak zainstalować narzędzie znajdziemy na https://docksal.io/
Po prawidłowej instalacji spróbujmy włączyć wirtualizację komendą
fin system start
Struktura katalogów
Stwórzmy teraz wstępną strukturę, która będzie szkieletem naszej aplikacji. W zależności od systemu na jakim pracujemy ścieżki będą się różnić. Ja pracuję na Windowsie ale ścieżki lokalne oprę o ścieżki linuksowe. Przyjmijmy, że nasze projektu znajdują się w katalogu
/var/www
co za tym idzie swoją stronę umieszczę
/var/www/onblue
Struktura ostateczna będzie wyglądała zatem tak
/var/www/onblue
/var/www/onblue/.docksal – pliki konfiguracyjne naszego środowiska
/var/www/onblue/docroot – pliki naszej aplikacji
/var/www/onblue/dump.sql – dump bazy naszej aplikacji
Do katalogu docroot wrzućmy aktualną wersję naszego kodu. A do katalogu konfiguracyjnego środowiska to, co niżej
/var/www/onblue/.docksal/commands/init
/var/www/onblue/.docksal/commands/url
/var/www/onblue/.docksal/docksal.env
/var/www/onblue/.docksal/docksal.yml
Odpowiednio init i url są plikami ze skryptem bashowym, który później pomoże nam w procesie odpalania lokalnej wersji projektu. W plikach docksal wprowadźmy co następuje
/var/www/onblue/.docksal/docksal.env
/var/www/onblue/.docksal/docksal.env
Obie konfiguracje nie mają niczego szczególnego oprócz docksal.yml, która ma dwa niestandardowe parametry, są to kolejno
Postaramy się, żeby nasza lokalna aplikacja działała pod domeną onblue.pl, a samą konfigurację bazy oprzemy o zmienne środowiskowe.
Żeby osiągnąć punkt pierwszy dotyczący domeny musimy odpowiednio dodać wpis do
/etc/hosts
w której zawrzemy informacje, że onblue.pl tyczy się adresu ip 192.168.64.100.
Nasze dane dostępowe do produkcyjnej bazy umieśćmy w pliku pod ścieżką
/var/www/onblue/.env.prod
Który może wyglądać następująco
Zmiennych środowiskowych lokalnych nie zmieniajmy, upewnijmy się tylko czy table_prefix zgadza się z tym ustawionym w bazie, której uprzednio zrobiliśmy backup.
Kolejnym krokiem będzie przygotowanie naszego pliku konfiguracyjnego, który pozwoli odczytywać wartości ze zmiennych środowiskowych.
By przystąpić do dalszych prac włączmy nasz projekt komendą
fin project start
dzięki czemu będziemy mogli korzystać z narzędzi zintegrowanych w Docksal.
Jednym z takich narzędzi jest Composer, który zastosujemy do ściągnięcia biblioteki https://github.com/vlucas/phpdotenv
Przejdźmy do katalogu z kodem źródłowym naszej aplikacji
cd /var/www/onblue/docroot
a następnie wykonajmy komendę, dzięki której ściągniemy potrzebną bibliotekę
fin composer require vlucas/phpdotenv
Po poprawnym przebiegu ściągnięcia jej lokalnie możemy przystąpić do zmodyfikowania naszego pliku wp-config.php
Na samej górze naszego pliku umieśćmy ładowanie zmiennych środowiskowych z pliku
a samą definicję konfiguracji zmieńmy na następującą
Dzięki temu, że nasze lokalne zmienne środowiskowe umieściliśmy w pliku konfiguracyjnym Docksala nie musimy martwić się o to, że nasz serwer tego nie odczyta. Z kolei biorąc pod uwagę fakt stawiania aplikacji na serwerze, gdzie proces obsługujący nasz skrypt nie ma dostępu do zmiennych środowiskowych musimy skorzystać z odczytywania ich z pliku.
Wgranie backupu bazy danych
Wróćmy do naszego katalogu nadrzędnego, gdzie będziemy obsługiwać cały proces wgrywania kodu na serwer produkcyjny.
cd /var/www/onblue
Wykorzystajmy fakt, że mamy odpalony proces wirtualizacji środowiska i wgrajmy nasz backup bazy danych
fin db import dump.sql
Jeżeli nic nie pominęliśmy powinniśmy móc wejść na lokalne środowisko https://onblue.pl/
.htaccess i Docksal commands
W tym momencie możemy zauważyć dwie rzeczy, mianowicie niepoprawny .htaccess, ponieważ mój produkcyjny różni się od lokalnego między innymi tym, że lokalnie nie obsługuję SSL, a produkcyjnie tak. Drugą sprawą jest fakt, że nie zmieniliśmy ustawień ścieżek w bazie dla WordPressa.
W katalogu aplikacji umieściłem dwa różniące się pliki .htaccess, kolejno .htaccess.dev i .htaccess.prod
Następnie wykorzystałem wcześniej przygotowane pliki
/var/www/onblue/.docksal/commands/init
/var/www/onblue/.docksal/commands/url
Które teraz pomogą mi w postawieniu lokalnie środowiska. Dla pliku init stworzymy skrypt, który ustawi nam poprawny plik .htaccess lokalnie
/var/www/onblue/.docksal/commands/init
Z kolei dla pliku url zrobimy możliwość wprowadzenia zmian w bazie dzięki klientowi WordPressa, który również jest zintegrowany z Docksalem
Wyłączmy na chwilę nasz projekt przez komendę
fin project stop
co pozwoli nam go włączyć dzięki naszemu dopiero co stworzonemu skryptowi, mianowicie
fin init
który wykona nam wszystko, co zawarliśmy w /var/www/onblue/.docksal/commands/init
Po poprawnym włączeniu aplikacji, wykonajmy
fin url
Od tego momentu nasze dane w bazie zmieniły się na te, określone w pliku url.
Tworzymy repozytorium
Następnym krokiem w celu osiągnięcia efektu, który długofalowo pomoże nam w utrzymaniu kodu będzie stworzenie repozytorium. W ten sposób będziemy mogli śledzić zmiany w kodzie, a w przypadku niepożądanych zachowań lub wydarzeń typu włamanie na stronę, będziemy mogli cofnąć kod do którejś z rewizji.
Pierwszą rzeczą jaką zrobimy to założenie repozytorium. Możemy to zrobić na jednej z darmowych usług, na przykład https://bitbucket.org/
Po założeniu repozytorium przejdziemy do katalogu z aplikacją
/var/www/onblue/docroot
Pamiętajmy, żeby nie śledzić zmian w katalogu wyżej, ponieważ śledzimy historię w plikach konfiguracyjnych, a więc wysyłamy na repozytorium hasła i inne wrażliwe dane. Jeżeli potrzebujemy wysłać katalog wyżej, pamiętajmy o wykluczeniu odpowiednich rzeczy w pliku .gitignore
Kolejną rzeczą, którą zrobimy to wygenerowanie klucza, dodanie go do repozytorium i serwera.
fin ssh-key new onblue_rsa
Gdzie onblue_rsa to nazwa klucza.
Z poziomu ustawień użytkownika na koncie bitbucket dodajmy klucz przez zakładkę Security i SSH keys.
Przyszedł czas na dodanie klucza do serwera. Służy do tego komenda
fin exec ssh-copy-id user@onblue.pl
Dzięki wyżej wymienionym komendom nie będziemy musięli autoryzować się hasłem, co w normalnej sytuacji jest mocno zalecane w sprawach typowo z poziomu bezpieczeństwa, tutaj przyspieszy proces.
Na koniec możemy sprawdzić czy jesteśmy autoryzowani poprawnym kluczem z poziomu bitbucketa. Służy do tego polecenie
fin exec ssh -T hg@bitbucket.org
Wyżej wymienione polecenie pomaga w przypadku debugowania, kiedy mamy więcej niż jeden klucz i obawiamy się, jeżeli musimy autoryzować się innym kluczem SSH.
Do katalogu z naszą aplikacją wrzućmy plik .gitignore, który wykluczy ze śledzenia zmian w konkretnych folderach i plikach. Wykorzystamy tutaj następujący listing https://github.com/github/gitignore/blob/master/WordPress.gitignore
Nawiążmy połączenie z naszym repozytorium tworząc konfigurację GIT
git init
git remote add origin git@bitbucket.org:user/onblue.git
git add .
git commit -m "init"
git push -u origin master
Deployer.phar
Dla sprawniejszego wdrożenia procesu deploymentu użyjemy narzędzia https://deployer.org/
Narzędzie przedstawione wyżej posiada w standardzie pewne założenia, a także formuły, których sami nie musimy pisać.
W katalogu wyżej niż nasza aplikacja ściągnimy binarny plik deployera.
fin exec curl -LO https://deployer.org/deployer.phar
fin exec chmod +x deployer.phar
Poniżej znajduje się listing kodu, który umieścimy pod ścieżką
/var/www/onblue/deploy.php
Ważne informacje co do wyżej wymienionego listingu to między innymi to, że korzystamy z przepisu na deploy kodu dla WordPressa. Kolejną rzeczą są trzy funkcje, które sami wdrożyliśmy. Jedna z nich prepare_htaccess odpowiada za to samo co nasz skrypt init lokalnie, mianowicie kopiuje .htacces.prod do pliku .htaccess na serwerze. Kolejną funkcją, o której wspominałem dużo wyżej jest skrypt do budowania aplikacji. W tym przypadku lokalnie wykonujemy proces composera, który instaluje dla nas potrzebne biblioteki. Taką funkcjonalność w przyszłości powinniśmy przebudować, między innymi do wdrożenia testów, budowania assetów i wiele więcej – w skrócie rzeczy, które nie powinny wykonać się na serwerze powinniśmy wykonać lokalnie albo na zdalnym serwerze, który odpowiada za deploy aplikacji. Jako, że wcześniej w pliku .gitignore umieściliśmy vendors do ignorowania ze śledzenia zmian powinniśmy wrzucić go ręcznie.
W punktach wyżej dodaliśmy klucze do serwera i repozytorium, a nie dodaliśmy klucza na serwerze, który pozwoli zautoryzować proces klonowania repozytorium na serwerze. Deployer łączy się z naszym SSH z flagą –A, która odpowiada za możliwość korzystania z kluczy klienta w pamięci, co pozwala pominąć proces kopiowania kluczy na serwer.
Jeżeli wszystkie zmienne ustawiliśmy na poprawne, powinniśmy móc przystąpić do procesu wgrania zmian na serwer produkcyjny.
Z katalogu
/var/www/onblue
Wykonajmy polecenie
fin exec php deployer.phar deploy –vvv
Po poprawnym wgraniu zmian powinien zostać zwrócony komunikat “Successfully deployed!“.
W związku z tym, że na serwerze nie mamy ustawionej zmiennej środowiskowej ENV nasz wp-config.php będzie próbował odczytać dane do bazy z pliku .env, z katalogu wyżej niż sam plik się znajduje.
Biorąc pod uwagę, że nasz skrypt znajduje się w tym miejscu
/home/user/web/onblue.pl/public_html/current
Skopiujmy nasz .env.prod do public_html. Pomoże nam w tym polecenie
fin exec scp .env.prod user@onblue.pl:/home/user/web/onblue.pl/public_html/.env
Upload mediów
Przed przełączeniem naszej domeny na nowy vhost zostało nam wgranie wszystkich plików z uploads, których nie śledzimy w repozytorium. Jak wyżej pomoże nam w tym narzędzie SCP
fin exec scp -r docroot/wp-content/uploads user@onblue.pl:/home/user/web/onblue.pl/public_html/shared/wp-content
Katalog shared jest współdzielony pomiędzy wszystkimi releases danej aplikacji.
Czego nie zrobiliśmy, a powinniśmy?
Jedną z rzeczy, które powinniśmy zrobić, a we wpisie nie zawarłem informacji o tym, to fakt, że przed wgraniem kolejnych zmian na serwer produkcyjny koniecznie powinniśmy zrobić backup przynajmniej katalogu z plikami dynamicznymi takimi jak te w uploads, a także wykonać dump bazy danych. Tak by w razie nieprzewidzianych komplikacji móc przywrócić te pliki.
Podsumowanie
Podsumowując wpis myślę, że zawarłem konkretną ilość informacji, by pokazać każdemu jak może wyglądać proces wdrażania zmian w aplikacji legacy, którą mamy się opiekować. Poświęcając niedużą ilość czasu w przygotowanie sobie podstaw pod wdrożenia, jesteśmy w stanie w przypadku chęci cofnięcia zmian, włamania na stronę internetową czy w przypadku, kiedy nad jedną aplikacją pracuje więcej niż jedna osoba. Prowadzona w ten sposób historia projektu jest transparentna dla klienta, a wdrożenie nowej osoby jest sprawniejsze niż tłumaczenie jej krok po kroku w jaki sposób wdrażać zmiany w aplikacji na serwerze produkcyjnym.