WordPress postawiony już dawno i nie chcesz zaczynać od zera? Nie jest to prawda i już mówię dlaczego!

Bedrock to nie tylko inna struktura folderów – to zmiana filozofii zarządzania WordPressem.

Przejście na Bedrock to krok w stronę profesjonalizacji workflow. Jak zauważyłem we wpisie Bedrock: WordPress w paradygmacie Twelve-Factor App, rozwiązanie to implementuje zasady nowoczesnych aplikacji (SaaS), takie jak:

  • Separacja konfiguracji od kodu: Wykorzystanie plików .env.
  • Zarządzanie zależnościami: Użycie Composera zamiast ręcznego wgrywania wtyczek.
  • Izolacja środowisk: Łatwiejsze wdrażanie zmian między środowiskiem lokalnym, stagingiem a produkcją.

Jak zmigrować?

Pełna instrukcja bazuje na oryginalnym wpisie z dodatkowymi adnotacjami ode mnie.

Dodam, że warto zaktualizować wszystko co można, do najnowszych wersji. Pluginy, wtyczki, czy sam core. Będę bazować w pełni na najnowszych wersjach, więc jeśli chcesz mieć jakieś starsze wersje – to elementy instalacji paczek (lub potem composer.json) trzeba dostosować pod swoje wersje (np.: przypiąć wersję).

Zabezpieczenie plików

W moim przypadku, WordPress był w katalogu: ~/domains/czarnaowca.it/public_html – więc mam katalog z publicznymi plikami i katalog danej strony. Zalecam zawsze mieć stronę w public_html lub podobnym, głębokim katalogiem, by móc w przyszłości realizować sporo zmian. A te zmiany? To zaraz opiszę.

cd ~/domains/
mv czarnaowca.it.bak.20260428
mkdir -p czarnaowca.it/public_html

W ten sposób przenieśliśmy katalog obok, by danych nie stracić (bo na nich będziemy mocno bazować).

Stwórzmy nowy projekt

Teraz możemy zainstalować na nowo projekt:

composer create-project roots/bedrock czarnaowca.it
cd czarnaowca.it

W ten sposób stworzyliśmy nową aplikację. Katalog publiczny jest w katalogu web i to ważna informacja – bo jak wspomniałem – u mnie to public_html. Wykorzystamy to co chwilowego zabezpieczenia strony nim ją zmigrujemy.

Robimy maintenance mode

W katalogu ~/domains/czarnaowca.it/public_html tworzymy dwa pliki: index.php oraz .htaccess (potrzeba tego pliku jest zależna od serwera www – jeśli nie wiesz jaki – zapraszam do skorzystania z mojego wsparcia).

<IfModule mod_rewrite.c>
    RewriteEngine On
    
    # Ignoruj istniejące pliki (np. obrazki, CSS, jeśli jakieś dodasz)
    RewriteCond %{REQUEST_FILENAME} !-f
    # Ignoruj istniejące katalogi
    RewriteCond %{REQUEST_FILENAME} !-d
    
    # Przekieruj wszystko inne do index.php
    RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
<?php
// Ustawienie nagłówków HTTP 503
header($_SERVER["SERVER_PROTOCOL"] . " 503 Service Temporarily Unavailable", true, 503);
header("Status: 503 Service Temporarily Unavailable");
header("Retry-After: 3600"); // Informacja dla botów (np. Google), by wróciły za godzinę (3600 sekund)
?>
<!DOCTYPE html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Strona w trakcie prac</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f4f4f9;
            color: #333;
        }
        .container {
            text-align: center;
            padding: 2.5rem;
            background: white;
            border-radius: 8px;
            box-shadow: 0 4px 15px rgba(0,0,0,0.05);
            max-width: 90%;
            width: 500px;
        }
        h1 {
            font-size: 2rem;
            margin-bottom: 1rem;
            color: #2c3e50;
        }
        p {
            font-size: 1.1rem;
            color: #555;
            line-height: 1.5;
        }
        .icon {
            font-size: 3rem;
            margin-bottom: 1rem;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="icon">🚧</div>
        <h1>Strona w trakcie prac</h1>
        <p>Przepraszamy, trwają prace konserwacyjne. <br>Wracamy wkrótce!</p>
    </div>
</body>
</html>

Te dwa pliki tam tworzymy – dzięki temu użytkownicy dostaną informację o pracach technicznych i strona będzie zwracać przyjemny dla SEO kod 503 – Serwis nie jest dostępny.

Strona bezpieczna, użytkownicy widzą informację, że pracujemy. Wyszukiwarki wiedzą, że kiedyś wrócimy. Nie będziemy sypać błędami i problemami na twarz, a tym samym zmniejszymy szanse na wyciek.

Kopiujemy co możemy

Oficjalnie twórca Bedrock zaleca w tym momencie skopiować pliki z wp-content do web/app – ja zaproponuję odejście do staroci i przejście do nowoczesności.

Pierw skopiujemy pliki i mu-plugins:

export KATALOG_KOPII=~/domains/czarnaowca.it.bak20260428/public_html                    # katalog naszej kopii
export KATALOG_NOWY=~/domains/czarnaowca.it                                             # katalog domowy aplikacji
rsync -av ${KATALOG_KOPII}/wp-content/uploads/ ${KATALOG_KOPII}/web/app/uploads/        # kopiujemy multimedia
rsync -av ${KATALOG_KOPII}/wp-content/mu-plugins/ ${KATALOG_KOPII}/web/app/mu-plugins/  # kopiujemy mu-pluginy

W ten sposób skopiujemy sobie multimedia (filmy, zdjęcia, itd) oraz mu-plugins.

A teraz będąc w tej samej sesji wyciągnijmy listę pluginów oraz listę katalogów:

find ${KATALOG_KOPII}/wp-content/plugins/ -maxdepth 1 -mindepth 1 -type d -exec basename {} \; # Lista pluginów
find ${KATALOG_KOPII}/wp-content/themes/ -maxdepth 1 -mindepth 1 -type d -exec basename {} \;  # Lista motywów

Na tej bazie szukamy wtyczek w repozytorium: wp-packages.org i zgodnie z instrukcją, instalujemy. Przykładowo dla wtyczki Yoast SEO wpisujemy komendę:

composer require wp-plugin/wordpress-seo

W ten sposób szukamy i instalujemy wszystkie wtyczki jakie posiadamy. Od tego momentu zarządzamy wtyczkami przy pomocy composer.

Wtyczka do migracji

Społeczność wie, że są problemy z kompatybilnością wpisów w bazie w wersji czystego WordPressa oraz Bedrock. Dlatego instalujemy kolejną wtyczkę:

composer require mwdelaney/lithify

Problem z Fatal error: Uncaught Error: Class "MWDelaney\Lithify\Init" not found in lithify.php:24

Na jednym z etapów migracji możemy spotkać problem z tym pluginem. Nie wiem z czego to wynika, bo nie znalazłem na ten problem odpowiedzi w oficjalnych źródłach. Jednakże moje rozwiązanie jest następujące:

Krok 1: Edycja root composer.json

Otwórz plik composer.json znajdujący się w głównym katalogu projektu i dodaj sekcję classmap do bloku autoload:

"autoload": {
  "psr-4": {
    "Roots\\": "web/app/mu-plugins/roots/"
  },
  "classmap": [
    "web/app/plugins/lithify/"
  ]
}
Krok 2: Optymalizacja autoloadera

Musimy teraz przebudować mapę klas, aby Composer „na sztywno” zaindeksował pliki wtyczki (w tym brakujący Init.php):

composer84 dump-autoload -o
Krok 3: Ponowna aktywacja

Teraz WP-CLI bez przeszkód odnajdzie wymagane klasy:

wp plugin activate lithify

Importujemy bazę

Oryginalną bazę backupujemy do pliku .sql na serwerze. Następnie kopiujemy plik .env.example jako .env. Teraz zaczniemy go edytować.

Pierw u naszego dostawcy tworzymy nową bazę MySQL i dane dostępowe uzupełniamy jako DB_HOST i inne zmienne w pliku.

AUTH_KEY='generateme'
SECURE_AUTH_KEY='generateme'
LOGGED_IN_KEY='generateme'
NONCE_KEY='generateme'
AUTH_SALT='generateme'
SECURE_AUTH_SALT='generateme'
LOGGED_IN_SALT='generateme'
NONCE_SALT='generateme'

Powyższe zmienne uzupełnijcie zgodnie z oryginalnymi wpisami w pliku wp-config.php w oryginalnej instancji WordPressa.

Jak już uzupełnimy plik, importujemy bazę komendą wp db import ścieżka/do/pliku.sql

Migracja właściwa

Aktywujemy plugin i migrujemy:

wp plugin activate lithify
wp lithify

Wtyczka wypluje nam trochę informacji i warto się z nimi zapoznać. Między innymi poda nam komendę, która pozwoli nam drastycznie uprościć element uzupełniania konfiguracji.

Wracamy!

Katalog public_html z nowego WordPressa zmieniamy nazwę na public_html.maintenance. Następnie symlinkujemy: ln -s public_html web.

W ten sposób strona wróciła do życia i zostało nam przetestować i szukać błędy.

Podsumowanie

Celowo pominąłem kilka kroków, by uchronić mniej doświadczonych osób.

Takim krokiem jest wersja środowiska i jak ją skonfigurować, gotowe komendy kopiuj-wklej, czy wyjaśnienia podstaw sposobu instalacji paczek.

Moją motywacją jest fakt, że praca z „waniliowym” WordPressem wymaga podstawowej wiedzy, zaś praca z Bedrock wymaga już doświadczenia w pracy z dobrej jakości środowiskiem, czyli współpraca z composerem, wp-cli, czy znajomość podstaw shella.

Jeśli nie rozumiesz wielu elementów, nie realizuj poradnika jako kopiuj-wklej, bo Bedrock, czy wtyczek nie aktualizuje się jak w czystym WP, że klikamy aktualizuj i gotowe.

Bedrock jest rozwiązaniem dla poważniejszych stron i doświadczonych programistów, którzy rozumieją jak działa git, czy jakie korzyści niesie praca z Bedrock ponad czystym WordPressem.

Dołącz do newslettera, by być na bieżąco!

Jeśli chcesz być na bieżąco z blogiem, otrzymywać świetne porady dot. programowania i administracji serwerami, opinie w temacie gier - dołącz do newslettera!

Raz na jakiś czas wyślę Ci informację nt. bloga, a także będę wysyłać ekskluzywne materiały techniczne!

Nie czekaj i dołącz!

Dołączając do newslettera, akceptujesz naszą politykę prywatności!