Jak stworzyć stronę staging PrestaShop
Kompletny przewodnik po konfiguracji środowiska testowego PrestaShop: Docker, hosting współdzielony i opcje lokalne. Aktualizacje psują staging, nie sklep.
Dlaczego przy każdym projekcie prowadzimy sklep staging
W mypresta.rocks równolegle utrzymujemy kilka środowisk staging, w tym ps9-dev, ps8-dev, ps178-dev oraz ps176-dev, a do tego sklepy dedykowane klientom, gdy dany projekt potrzebuje własnego klona. Nie są one luksusem. To dzięki nim testujemy każdą aktualizację modułu, każdą aktualizację PrestaShop i każdą zmianę motywu, zanim zobaczy je jakikolwiek klient. Po dekadzie dostarczania modułów nie spotkaliśmy ani jednego sprzedawcy, który żałowałby skonfigurowania takiego środowiska, za to wielu żałowało jego pominięcia.
Schemat jest zawsze ten sam: nieprzetestowana aktualizacja modułu trafia na produkcję, o 9:00 psuje się strona główna, o 9:05 pojawia się zgłoszenie do wsparcia, a kolejną godzinę spędza się na debugowaniu na oczach prawdziwych klientów. Zbudowanie sklepu staging zajmuje godzinę i zamienia ten scenariusz w 20-minutową naprawę pod adresem, którego nikt nie widzi.
Koszt jednej godziny przestoju podczas wyprzedaży przewyższa koszt utrzymania środowiska testowego o dwa rzędy wielkości. Jeśli sprzedaż w internecie jest źródłem utrzymania, sklep staging jest niezbędny.
Czym właściwie jest sklep staging
To pełny klon sklepu produkcyjnego (te same pliki, ta sama baza danych, ten sam zestaw modułów) serwowany pod adresem, do którego dostęp ma wyłącznie właściciel sklepu i jego zespół. Te same ścieżki kodu, którymi przechodzą klienci, ta sama logika biznesowa, te same przypadki brzegowe. Jedyne różnice to nazwa hosta, dane logowania oraz, przy poprawnej konfiguracji, fakt, że nie wychodzą żadne prawdziwe wiadomości e-mail i nie są obciążane żadne prawdziwe karty.
To nie jest środowisko deweloperskie do pracy od zera ani kopia zapasowa. Oba te nieporozumienia kosztowały sprzedawców prawdziwe pieniądze: staging zostaje nadpisany w momencie odświeżenia, więc wszystko, co tam zbudowano i czego nie wdrożono na produkcję, przepada.
Czym jest staging
- Działającą kopią plików i bazy danych z produkcji
- Na osobnej domenie lub subdomenie (stosujemy
staging.yourshop.comlubdev.yourshop.com) - Zabezpieczoną listą dozwolonych adresów IP lub uwierzytelnianiem basic, tak aby dostęp miał wyłącznie zespół
- Miejscem, w którym ćwiczy się aktualizacje modułów, zmiany motywu i aktualizacje PHP
Czym nie jest
- Piaskownicą deweloperską do budowania nowego kodu od podstaw, to osobny sklep dev
- Kopią zapasową. Kopie zapasowe są niezmienne. Staging jest nadpisywany przy każdym odświeżeniu.
- Konfiguracją typu „ustaw i zapomnij”. Sklep staging niezsynchronizowany z produkcją od pół roku nie wychwyci niczego.
Opcja 1: staging oparty na Dockerze (z tego korzystamy)
Wszystkie nasze sklepy staging działają w Dockerze na pojedynczej maszynie TrueNAS. Każdy sklep to jeden stos docker-compose we wspólnej sieci Docker, kontener PrestaShop, kontener MySQL, współdzielony Redis, jeden bind mount dla katalogu html i jeden dla danych MySQL. Nową wersję PS możemy uruchomić w niecałe pięć minut, a po zakończeniu pracy usunąć ją, aby zwolnić pamięć RAM. Po jednorazowym przejściu tej drogi nie wraca się już do „po prostu zainstaluję to w podkatalogu cPanel”.
Wymagania wstępne
- Host z systemem Linux z co najmniej 2 GB RAM na każdy sklep staging (4 GB, jeśli panel administracyjny ma działać płynnie)
- Zainstalowane i działające Docker oraz Docker Compose
- Dostęp SSH zarówno do produkcji, jak i do stagingu
- Swoboda w kopiowaniu i wklejaniu poleceń powłoki
Krok 1: plik compose
Należy utworzyć katalog oraz plik docker-compose.yml:
mkdir ~/your-shop-staging && cd ~/your-shop-staging
cat > docker-compose.yml <<'EOF'
version: '3.8'
services:
prestashop:
image: prestashop/prestashop:8.2
container_name: <your-shop>
ports:
- "8080:80"
environment:
- DB_SERVER=db
- DB_NAME=prestashop
- DB_USER=root
- DB_PASSWD=your_secure_password
volumes:
- ./html:/var/www/html
depends_on:
- db
restart: unless-stopped
db:
image: mysql:5.7
container_name: <your-shop>-db
environment:
- MYSQL_ROOT_PASSWORD=your_secure_password
- MYSQL_DATABASE=prestashop
volumes:
- ./mysql:/var/lib/mysql
restart: unless-stopped
EOF
Tag obrazu PrestaShop musi dokładnie odpowiadać wersji produkcyjnej. Jeśli produkcja działa na 1.7.8.11, należy użyć prestashop/prestashop:1.7.8.11, a nie 1.7. Widzieliśmy, jak sprzedawcy godzinami gonili widmowe błędy, ponieważ staging był na 1.7.8.10, a produkcja na 1.7.8.11, różnica na tyle mała, że wygląda identycznie, ale na tyle duża, że zachowanie jest inne.
Krok 2: zrzut produkcji
Należy połączyć się przez SSH z produkcją i uruchomić mysqldump. Na działającym sklepie warto użyć --single-transaction, aby nie zablokować tabeli zamówień, gdy klienci finalizują zakupy:
# Na serwerze produkcyjnym
mysqldump -u root -p prestashop > ~/prestashop_backup.sql
# Pobrać na komputer lokalny / serwer staging
scp user@production-server:~/prestashop_backup.sql ./
Krok 3: import do stagingu
# Uruchomić kontenery
docker compose up -d
# Odczekać ~30 sekund na inicjalizację MySQL, następnie zaimportować
docker exec -i <your-shop>-db mysql -u root -pyour_secure_password prestashop < prestashop_backup.sql
Jeśli MySQL zgłosi problem z zestawem znaków podczas importu, należy dodać SET NAMES utf8mb4; na początku pliku SQL. Spędziliśmy więcej czasu, niż chcielibyśmy przyznać, debugując podwójnie zakodowane UTF-8 na stagingu, którego na produkcji nie było.
Krok 4: kopiowanie plików produkcyjnych
# Zsynchronizować pliki produkcyjne z katalogiem html stagingu
rsync -avz --delete \\
user@production-server:/var/www/html/ \\
./html/ \\
--exclude='var/cache/*' \\
--exclude='var/logs/*' \\
--exclude='app/config/parameters.php'
Z rsync należy zawsze wykluczać parameters.php. Dane logowania do bazy w tym pliku należą do produkcji, jeśli pozwoli się rsync je nadpisać, sklep staging spróbuje połączyć się z produkcyjną bazą danych, co jest najgorszym możliwym skutkiem „konfigurowania stagingu”. Nauczyliśmy się tego boleśnie przy projekcie klienta w 2017 roku i od tego czasu automatycznie dopisujemy ten przełącznik wykluczenia.
Należy też wykluczyć wszelkie katalogi runtime, do których sklep zapisuje na produkcji. Sitemapy, generowane obrazy, które nie są potrzebne, katalogi kopii zapasowych, klucze licencyjne. rsync --delete czyści stronę docelową, a nadgorliwe użycie rsync nieraz na naszych oczach usuwało wygenerowane sitemapy i psuło Google Search Console.
Krok 5: przepisanie adresów URL i wyczyszczenie cache
Najczęstsza przyczyna pytania „dlaczego mój sklep staging nie działa”: ps_shop_url nadal wskazuje na produkcję. Należy to naprawić:
docker exec -i <your-shop>-db mysql -u root -pyour_secure_password prestashop -e "
UPDATE ps_shop_url SET domain='staging.yourshop.com', domain_ssl='staging.yourshop.com' WHERE id_shop=1;
UPDATE ps_configuration SET value='staging.yourshop.com' WHERE name IN ('PS_SHOP_DOMAIN','PS_SHOP_DOMAIN_SSL');
"
Należy zaktualizować html/app/config/parameters.php, wpisując dane logowania do bazy staging z pliku compose. Następnie trzeba wyczyścić cache:
docker exec <your-shop> rm -rf /var/www/html/var/cache/*
Pominięcie czyszczenia cache sprawia, że skompilowane szablony Smarty nadal zawierają adres URL produkcji, co skutkuje pętlami przekierowań z powrotem do sklepu produkcyjnego. Na każdym sklepie używającym OPcache (czyli na wszystkim, co jest na produkcji) należy dodatkowo zrestartować PHP-FPM lub wywołać endpoint resetujący OPcache.
Opcja 2: subdomena na hostingu współdzielonym
Docker nie jest dostępny na cPanel, Plesk ani DirectAdmin. Ten sam efekt można uzyskać dzięki subdomenie, drugiej bazie danych i kopii plików.
Utworzenie subdomeny
- W panelu hostingu należy przejść do Subdomeny lub Domeny
- Należy dodać
staging.yourshop.com - Należy skierować ją do nowego katalogu, np.
/home/user/staging.yourshop.com
Utworzenie osobnej bazy danych
- Należy otworzyć Bazy danych MySQL
- Należy utworzyć bazę o nazwie np.
user_staging - Należy utworzyć lub przypisać użytkownika z pełnymi uprawnieniami do tej bazy
Kopiowanie plików i import zrzutu
Przez SSH:
cp -r /home/user/public_html/* /home/user/staging.yourshop.com/
# Eksport produkcji
mysqldump -u user -p production_db > ~/staging_import.sql
# Import do stagingu
mysql -u user -p staging_db < ~/staging_import.sql
Należy zedytować app/config/parameters.php (lub config/settings.inc.php na 1.6), aby wskazywał nową bazę danych, a następnie uruchomić to samo SQL przepisujące adresy URL z opcji 1, krok 5. Nie wolno zapomnieć o usunięciu var/cache/ na koniec.
Opcja 3: lokalne środowisko deweloperskie z XAMPP/MAMP
Sprawdza się przy pracy typu „szybkie sprawdzenie ekranu administracyjnego tego modułu przez dziesięć minut”, ale do czegokolwiek innego jest bezużyteczne. Wersja PHP, wersja MySQL, model uprawnień plików oraz rozszerzenia na poziomie systemu operacyjnego będą się różnić od serwera produkcyjnego. Sami korzystamy z lokalnych stosów, lecz nigdy jako ostatniego testu przed wdrożeniem: wszystko, co ma wkrótce trafić na produkcję, jest ponownie testowane na serwerowym stagingu odwzorowującym środowisko produkcyjne.
Po konfiguracji: rzeczy, które dają się we znaki, jeśli się o nich zapomni
Natychmiast zablokować wychodzące wiadomości e-mail
Baza danych stagingu zawiera każdy prawdziwy adres e-mail klienta. Wyzwolenie resetu hasła, potwierdzenia zamówienia lub crona z powiadomieniami o stanie magazynowym sprawia, że te wiadomości trafiają do prawdziwych klientów. Widzieliśmy, jak sprzedawcy publicznie przepraszali, ponieważ ich cron na stagingu wysłał „Zamówienie zostało wysłane” do tysiąca prawdziwych klientów, których zamówienia w rzeczywistości nie zostały wysłane.
Należy przejść do Parametry zaawansowane → E-mail i wybrać jedną z opcji:
- Ustawić metodę na „Nigdy nie wysyłaj wiadomości e-mail”: jedyną w pełni bezpieczną opcję
- Przekierować całość przez Mailtrap, aby nadal można było sprawdzać wyrenderowane wiadomości bez ich dostarczania
Wyłączyć moduły płatności
Stripe, PayPal, Klarna, Adyen: wszystko, co jest połączone z aktywnym kontem rozliczeniowym. Na stagingu należy albo całkowicie wyłączyć te moduły, albo przełączyć każdy z nich w tryb sandbox/test. To samo dotyczy interfejsów API przewoźników (etykiety UPS, DHL, GLS) oraz każdego modułu wywołującego usługę zewnętrzną o płatnych skutkach ubocznych.
Zablokować wyszukiwarki
Sklep staging zaindeksowany przez Google to katastrofa duplikacji treści. Dla pewności należy zadbać o trzy rzeczy:
- Wyłączyć mapę witryny XML w Parametry sklepu → Ruch i SEO
- Umieścić w katalogu głównym plik
robots.txtzUser-agent: *orazDisallow: / - Jeszcze lepiej całkowicie zablokować dostęp publiczny (następna sekcja), aby Google w ogóle nie dotarło do sklepu
Zabezpieczyć sklep listą dozwolonych adresów IP
Najbardziej niezawodnym podejściem jest ograniczenie dostępu po adresie IP na poziomie Apache lub Nginx. Tryb konserwacji można obejść, jeśli ustawienie listy dozwolonych adresów IP zawiera błąd, a uwierzytelnianie HTTP Basic Auth czasem psuje moduły intensywnie korzystające z AJAX-a (widzieliśmy, jak rozkłada nasze własne panele administracyjne, gdy przeglądarka nie potrafiła przenieść nagłówka uwierzytelniania przez XHR). Lista dozwolonych adresów IP na poziomie serwera WWW przechwytuje wszystko, zanim PrestaShop w ogóle się uruchomi.

Utrzymywanie stagingu w synchronizacji z produkcją
Sklep staging przestarzały o trzy miesiące jest gorszy niż brak stagingu, daje fałszywe poczucie pewności. My odświeżamy swoje według harmonogramu oraz przed każdym istotnym wdrożeniem.
Kiedy odświeżać
- Przed każdą znaczącą zmianą: aktualizacją modułu, aktualizacją rdzenia, podbiciem wersji PHP, przeróbką motywu
- Co najmniej raz w miesiącu w przypadku aktywnego rozwoju
- Po każdej dużej zmianie w katalogu na produkcji, nowych drzewach kategorii, strukturalnych zmianach produktów, przetasowaniach cech/atrybutów
Skrypt odświeżający (Docker)
#!/bin/bash
# refresh-staging.sh: Pobrać najnowsze dane produkcyjne do stagingu
# 1. Zrzucić bazę danych produkcji
ssh production "mysqldump -u root -p'PASS' prestashop" > /tmp/staging_refresh.sql
# 2. Zaimportować do stagingu
docker exec -i <your-shop>-db mysql -u root -p'your_secure_password' prestashop < /tmp/staging_refresh.sql
# 3. Naprawić adresy URL
docker exec -i <your-shop>-db mysql -u root -p'your_secure_password' prestashop -e "
UPDATE ps_shop_url SET domain='staging.yourshop.com', domain_ssl='staging.yourshop.com' WHERE id_shop=1;
UPDATE ps_configuration SET value='staging.yourshop.com' WHERE name IN ('PS_SHOP_DOMAIN','PS_SHOP_DOMAIN_SSL');
"
# 4. Zsynchronizować pliki
rsync -avz --delete production:/var/www/html/ ./html/ --exclude='var/cache/*' --exclude='app/config/parameters.php'
# 5. Wyczyścić cache
docker exec <your-shop> rm -rf /var/www/html/var/cache/*
echo "Staging refreshed."
Błędy, które nadal widzimy u sprzedawców
Pozostawione klucze API produkcji
Liczba sklepów staging, które audytowaliśmy, a które po cichu wysyłały prawdziwe obciążenia Stripe, odpytywały prawdziwe API przewoźników o etykiety śledzenia na żywo lub zjadały limity prawdziwego API, ponieważ klucze przyszły razem z bazą danych, jest niepoliczalna. Każde zewnętrzne dane uwierzytelniające należy zmienić na klucz sandbox na stagingu w chwili, gdy baza danych trafi na miejsce, jeszcze przed otwarciem panelu administracyjnego.
Wciąż uruchamiające się crony
Jeśli na produkcji skonfigurowano zadania cron (przypomnienia o porzuconych koszykach, synchronizacja stanów magazynowych, generowanie feedów, odnawianie licencji), należy sprawdzić, czy panel hostingu lub timery systemd nie uruchamiają tych samych zadań na nazwie hosta stagingu. Mieliśmy klienta, którego sklep staging przez dwa tygodnie radośnie wysyłał prawdziwe aktualizacje stanów magazynowych Allegro, zanim ktokolwiek to zauważył.
Oba panele administracyjne otwarte w tej samej przeglądarce
Ciasteczka panelu administracyjnego PrestaShop są ograniczone do domeny, ale konflikty sesji i tak się zdarzają, gdy oba sklepy są zalogowane w tej samej przeglądarce. Do stagingu należy używać osobnej przeglądarki, osobnego profilu lub okna incognito. Każdy członek naszego zespołu ma dedykowany profil Firefox do sklepów staging klientów.
Kiedy testować na stagingu, a kiedy produkcja wystarczy
| Zawsze najpierw na stagingu | Bezpiecznie bezpośrednio na produkcji |
|---|---|
| Aktualizacje rdzenia PrestaShop (1.7 → 8, 8 → 9) | Edycje treści, strony CMS, opisy produktów |
| Instalacje modułów lub podbicia wersji głównej | Zmiany cen |
| Aktualizacje motywu lub praca nad motywem potomnym | Włączanie/wyłączanie już przetestowanych modułów |
| Podbicia wersji PHP | Dodawanie nowych produktów, kategorii, tagów |
| Własny kod, nadpisania, dekoratory usług | Edycje reguł wysyłki lub podatków |
| Migracje bazy danych lub strukturalne SQL | Drobne korekty tłumaczeń |
Warte tej godziny
Pierwsza konfiguracja stagingu zajmuje około godziny. Odświeżenie, gdy skrypt jest już gotowy, to pięć minut. Za pierwszym razem, gdy staging wychwyci aktualizację modułu, która zepsułaby proces realizacji zakupu, inwestycja zwróci się dziesięciokrotnie, i widzieliśmy, jak dzieje się to na prawdziwych sklepach, które prowadzimy. Po Docker sięgnęlibyśmy w przypadku posiadania VPS-a lub dedykowanej maszyny; klonowanie na subdomenie to właściwy wybór na hostingu współdzielonym. Tak czy inaczej, cel jest ten sam: nic nieprzetestowanego nie dotyka klientów.
Jeśli staging jest konfigurowany właśnie po to, by testować nasze moduły, nasz program Wypróbuj przed zakupem daje pełne 30-dniowe demo dowolnego modułu. Można go zainstalować na stagingu, przetestować w boju i zdecydować przed zapłatą.
Powiązane materiały
- Jak poprawnie testować moduły PrestaShop: co właściwie robić, gdy staging już działa
- Lokalne środowisko deweloperskie PrestaShop: konfiguracja XAMPP, WAMP, Docker i Linux: etap lokalnego środowiska deweloperskiego przed stagingiem
- Docker dla PrestaShop: konfiguracja środowiska deweloperskiego: jak szczegółowo prowadzimy nasze kontenery
- Konfiguracja Dockera dla PrestaShop: środowiska deweloperskie i produkcyjne
- Usuwanie zamówień testowych: czyszczenie PrestaShop przed uruchomieniem produkcyjnym
Powiązane moduły
- Password Protection: zablokowanie sklepu staging hasłem / listą dozwolonych adresów IP
- MPR Cron Manager: kontrola nad tym, które crony uruchamiają się na stagingu
- Performance Revolution: testowanie zmian wydajnościowych, zanim trafią na produkcję