WordPress jest strasznie popularnym systemem CMS na świecie. Praktycznie każdy miał okazję korzystać z niego w ten, czy inny sposób. Jako programista, administrator, dział wsparcia klienta, czy po prostu użytkownik takiej strony. Nawet mój blog jest oparty o WordPress, chociaż nie jestem jego fanem. Niestety to system okropnie napisany, co dzisiaj możemy nazwać – niezgodnie ze sztuką. Co z tym zrobić?
Kryzys Tożsamości Tradycyjnego WordPressa i Narodziny Nowoczesnego Stacku
Ekosystem WordPressa, zasilający ponad 40% internetu, znajduje się w punkcie zwrotnym swojej ewolucji technologicznej. Przez blisko dwie dekady platforma ta demokratyzowała publikowanie treści w sieci, oferując niski próg wejścia i bezprecedensową łatwość obsługi dla użytkowników końcowych. Jednakże ta sama architektura, która umożliwiła masową adopcję – oparta na przesyłaniu plików przez FTP, edycji kodu bezpośrednio na serwerze produkcyjnym oraz przechowywaniu konfiguracji wewnątrz katalogu aplikacji – stała się głównym hamulcem dla profesjonalnych zespołów inżynierskich dążących do wdrażania standardów DevOps. W środowisku korporacyjnym, gdzie wymagana jest powtarzalność wdrożeń, skalowalność i rygorystyczne bezpieczeństwo, „Vanilla WordPress” (standardowa instalacja) jawi się jako relikt minionej epoki PHP.
W odpowiedzi na te wyzwania, zespół Roots.io opracował Bedrock – rozwiązanie, które nie jest forkiem (rozgałęzieniem) samego silnika CMS, lecz radykalną zmianą struktury i filozofii zarządzania projektem WordPress. Bedrock to „boilerplate” (szablon startowy), który implementuje zasady metodologii Twelve-Factor App w świecie WordPressa, przekształcając go z monolitycznego skryptu blogowego w nowoczesną aplikację PHP zarządzaną przez menedżer zależności Composer.
Przeanalizujemy sobie ten system, by zrozumieć architekturę tego rozwiązania, bezpieczeństwo, czy zarządzanie zależnościami.
Bedrock – architektura
Zrozumienie Bedrocka wymaga porzucenia przyzwyczajeń wyniesionych z pracy ze standardowym WordPressem. W tradycyjnym modelu struktura katalogów jest płaska i miesza pliki jądra (core), pliki konfiguracyjne oraz zasoby użytkownika (uploads, themes, plugins) w jednej przestrzeni dostępnej publicznie. Bedrock wprowadza ścisłą separację tych obszarów, co ma fundamentalne znaczenie dla bezpieczeństwa i łatwości utrzymania.
Struktura katalogów
Różnice w strukturze plików nie są jedynie kosmetyczne; odzwierciedlają one głęboką zmianę w podejściu do tego, co stanowi „kod aplikacji”, a co jest „konfiguracją” lub „zależnością”.
| Komponent Systemu | Vanilla WordPress (Standard) | Bedrock | Konsekwencje |
| Punkt Wejścia (Web Root) | Główny katalog projektu (/) | Podkatalog /web | Izolacja plików systemowych od publicznego dostępu. |
| Jądro Systemu (Core) | Wymieszane w głównym katalogu | Odseparowane w /web/wp | Możliwość traktowania WP jako zewnętrznej zależności (Git submodule/Composer package). |
Katalog Treści (wp-content) | /wp-content | /web/app | Zgodność ze standardami nazewnictwa aplikacji webowych; separacja od jądra. |
| Konfiguracja Główna | /wp-config.php | /config/application.php | Dynamiczne ładowanie konfiguracji; brak haseł w kodzie. |
| Zmienne Środowiskowe | Brak (logika w PHP) | Plik .env (biblioteka Dotenv) | Parytet środowisk (Dev/Stage/Prod); bezpieczeństwo poświadczeń. |
| Zależności (Wtyczki/Motywy) | W repozytorium (często) | composer.json / vendor | Repozytorium zawiera tylko definicje wersji, a nie kod źródłowy bibliotek. |
| Wtyczki Wymagane (Mu-plugins) | Pojedyncze pliki w katalogu | Autoloader + Composer | Obsługa złożonych wtyczek jako mu-plugins; wersjonowanie. |
Izolacja Katalogu Publicznego (Web Root Isolation)
Jednym z najbardziej krytycznych aspektów architektury Bedrocka jest przeniesienie punktu wejścia serwera WWW (DocumentRoot) do podkatalogu /web. W standardowej instalacji WordPressa, pliki takie jak wp-config.php (zawierający hasła do bazy danych), readme.html (zdradzający wersję WP), czy katalog .git (zawierający historię zmian) znajdują się w tym samym katalogu co index.php. Oznacza to, że przy błędnej konfiguracji serwera (np. brak obsługi PHP, brak reguł w .htaccess), pliki te mogą zostać pobrane przez atakującego bezpośrednio przez przeglądarkę.
W Bedrocku struktura wygląda następująco:
├── composer.json
├── config
│ ├── application.php # Primary wp-config
│ └── environments
│ ├── development.php
│ ├── staging.php
│ └── production.php
├── vendor # Composer dependencies
└── web # Public document root
├── app # WordPress content dir
│ ├── mu-plugins
│ ├── plugins
│ ├── themes
│ └── uploads
├── wp-config.php
├── index.php
└── wp # WordPress core
Serwer WWW (Nginx lub Apache) jest skonfigurowany tak, aby serwować pliki wyłącznie z katalogu /web. Dzięki temu, nawet w przypadku awarii interpretera PHP lub błędu konfiguracji serwera, plik .env zawierający krytyczne dane uwierzytelniające jest fizycznie niedostępny z poziomu protokołu HTTP, ponieważ znajduje się poziom wyżej w hierarchii systemu plików. Jest to implementacja zasady „defense in depth” (obrona w głąb).
Transformacja wp-content w /web/app
Bedrock zrywa z konwencją nazewnictwa wp-content, przemianowując ten katalog na app i umieszczając go wewnątrz /web. Decyzja ta ma na celu lepsze odzwierciedlenie struktury nowoczesnych aplikacji webowych, gdzie katalog app zawiera logikę biznesową i zasoby specyficzne dla danego projektu.
Wewnątrz /web/app znajdziemy:
/plugins: Zainstalowane wtyczki./themes: Motywy./uploads: Pliki przesyłane przez użytkowników./mu-plugins: Wtyczki „Must Use”.
Co istotne, Bedrock definiuje nowe stałe w konfiguracji WordPressa (WP_CONTENT_DIR, WP_CONTENT_URL), aby poinformować jądro o nowej lokalizacji zasobów. Większość nowoczesnych wtyczek respektuje te stałe, jednak starsze rozwiązania, które „hardcodują” ścieżkę wp-content, mogą wymagać poprawek lub nie działać poprawnie w tym środowisku.
Zarządzanie Zależnościami: Rewolucja Composer i WPackagist
Wprowadzenie Composera do ekosystemu WordPress jest prawdopodobnie najważniejszą innowacją oferowaną przez Bedrock. Composer to standardowy menedżer zależności dla języka PHP, analogiczny do npm w JavaScript czy pip w Pythonie. W tradycyjnym WordPressie zarządzanie wtyczkami odbywa się manualnie (przez panel admina lub FTP), co prowadzi do problemów z synchronizacją wersji między środowiskami deweloperskim, testowym i produkcyjnym.
WordPress jako Zależność (roots/wordpress)
W filozofii Bedrocka, sam WordPress nie jest „aplikacją”, którą instalujemy, lecz „zależnością”, którą pobieramy. W pliku composer.json znajduje się wpis:
"require": {
"roots/wordpress": "1.28.3"
}
Pakiet roots/wordpress to specjalnie przygotowana wersja WordPressa, która jest pozbawiona katalogu wp-content i służy jedynie jako biblioteka jądra. Dzięki temu aktualizacja WordPressa sprowadza się do zmiany numeru wersji w composer.json i wykonania komendy composer update. Eliminuje to ryzyko nadpisania plików konfiguracyjnych lub modyfikacji dokonanych w jądrze (które w Bedrocku są surowo zabronione i technicznie utrudnione).
WPackagist: Most Technologiczny między SVN a Composerem
Oficjalne repozytorium wtyczek WordPress (WordPress.org) nie obsługuje natywnie Composera. Aby umożliwić instalację wtyczek z oficjalnego źródła przy użyciu standardów PHP, społeczność stworzyła WordPress Packagist (WPackagist). Jest to usługa, która mapuje repozytorium SVN WordPressa na pakiety Composera.
Mechanizm ten pozwala na instalację dowolnej wtyczki z katalogu WordPress.org poprzez dodanie prefiksu wpackagist-plugin/ lub wpackagist-theme/ do jej nazwy (slug).
Przykład instalacji popularnych wtyczek w Bedrocku:
- Yoast SEO:
composer require wpackagist-plugin/wordpress-seo - WooCommerce:
composer require wpackagist-plugin/woocommerce - Classic Editor:
composer require wpackagist-plugin/classic-editor
Bedrock ma domyślnie skonfigurowane repozytorium WPackagist w swoim composer.json:
"repositories": [
{
"type": "composer",
"url": "https://wpackagist.org",
"only": [
"wpackagist-plugin/*",
"wpackagist-theme/*"
]
}
]
Dzięki temu deweloperzy mają dostęp do dziesiątek tysięcy wtyczek bez konieczności manualnego pobierania plików ZIP.
Rola Pliku composer.lock w Zapewnieniu Integralności
Kluczowym elementem stabilności systemu jest plik composer.lock. Podczas gdy composer.json definiuje przybliżone wymagania wersji (np. ^6.0 – każda wersja wyższa lub równa 6.0, ale niższa niż 7.0), plik composer.lock zapisuje dokładną sumę kontrolną (hash) konkretnej zainstalowanej wersji pakietu.
Gdy inny deweloper lub serwer wdrażania (CI/CD) uruchamia komendę composer install, Composer ignoruje composer.json i instaluje dokładnie te wersje, które są zapisane w pliku .lock. Gwarantuje to absolutną powtarzalność środowiska. Eliminuje to klasyczny problem „u mnie działa”, gdzie na produkcji zainstalowała się nowsza wersja wtyczki z błędem, podczas gdy deweloper testował na starszej, stabilnej wersji.
Niestandardowe Ścieżki Instalacji (installer-paths)
Domyślnie Composer instaluje wszystkie pakiety w katalogu vendor/. Wtyczki WordPress muszą jednak znajdować się w konkretnych lokalizacjach, aby CMS mógł je wykryć. Bedrock wykorzystuje pakiet composer/installers oraz sekcję konfiguracyjną extra w composer.json, aby przesuwać pliki wtyczek i motywów do odpowiednich podkatalogów w /web/app.
Fragment konfiguracji composer.json odpowiedzialny za to mapowanie:
"extra": {
"installer-paths": {
"web/app/mu-plugins/{$name}/": ["type:wordpress-muplugin"],
"web/app/plugins/{$name}/": ["type:wordpress-plugin"],
"web/app/themes/{$name}/": ["type:wordpress-theme"]
},
"wordpress-install-dir": "web/wp"
}
Dzięki tej konfiguracji, mimo że wtyczki są zarządzane jako zależności zewnętrzne, fizycznie trafiają do struktury katalogów wymaganej przez architekturę WordPressa.
Konfiguracja i Środowiska: Implementacja Dotenv
Bedrock całkowicie rezygnuje z przechowywania poufnych danych konfiguracyjnych w plikach PHP podlegających wersjonowaniu. Zamiast tego, wykorzystuje bibliotekę vlucas/phpdotenv do ładowania zmiennych środowiskowych z pliku .env.
Plik .env i Bezpieczeństwo Poświadczeń
.env znajduje się w katalogu głównym projektu (poza web root) i zawiera definicje takie jak:
- Dane dostępowe do bazy danych (
DB_NAME,DB_USER,DB_PASSWORD). - Adresy URL aplikacji (
WP_HOME,WP_SITEURL). - Tryb pracy środowiska (
WP_ENV). - Klucze szyfrujące i sole (Salts).
Jest domyślnie dodany do .gitignore, co oznacza, że nigdy nie jest przesyłany do repozytorium kodu. Każde środowisko (lokalne dewelopera, staging, produkcja) posiada własny, unikalny plik .env dostosowany do specyfiki danej infrastruktury. Jest to fundamentalna zasada bezpieczeństwa nowoczesnych aplikacji webowych, zapobiegająca wyciekom haseł poprzez repozytoria Git.
Dynamiczna Konfiguracja: config/application.php
Tradycyjny plik wp-config.php w Bedrocku został zastąpiony przez config/application.php. Plik ten pełni rolę mostu między zmiennymi środowiskowymi a stałymi WordPressa.
Przykład mapowania w application.php:
/**
* Set up our global environment constant and load its config first
* Default: production
*/
define('WP_ENV', getenv('WP_ENV')?: 'production');
$env_config = __DIR__. '/environments/'. WP_ENV. '.php';
if (file_exists($env_config)) {
require_once $env_config;
}
/**
* URLs
*/
define('WP_HOME', getenv('WP_HOME'));
define('WP_SITEURL', getenv('WP_SITEURL'));
/**
* DB settings
*/
define('DB_NAME', getenv('DB_NAME'));
define('DB_USER', getenv('DB_USER'));
define('DB_PASSWORD', getenv('DB_PASSWORD'));
Taka konstrukcja pozwala na dynamiczne dostosowanie zachowania aplikacji. Na przykład, definiując WP_ENV='development' w pliku .env, Bedrock załaduje dodatkowy plik konfiguracyjny config/environments/development.php, który włącza debugowanie (WP_DEBUG, WP_DEBUG_LOG) i wyłącza cache. Z kolei na produkcji (WP_ENV='production'), ładowany jest plik production.php, który wyłącza wyświetlanie błędów i blokuje edycję plików (DISALLOW_FILE_MODS), co znacząco podnosi bezpieczeństwo.
Zarządzanie Kluczami (Salts)
W standardowym WordPressie klucze szyfrujące (Salts) są często generowane raz przy instalacji i zapisywane w wp-config.php. W Bedrocku są one również zarządzane przez zmienne środowiskowe. Umożliwia to ich łatwą rotację bez konieczności zmiany kodu aplikacji – wystarczy zaktualizować wartości w pliku .env na serwerze i przeładować konfigurację PHP, co automatycznie wyloguje wszystkich użytkowników i unieważni sesje, co jest kluczową procedurą w przypadku podejrzenia incydentu bezpieczeństwa.
System Wtyczek Wymaganych (Mu-plugins) i Autoloader
Wtyczki „Must-Use” (mu-plugins) to specyficzny mechanizm WordPressa, pozwalający na instalację skryptów, które są uruchamiane przed zwykłymi wtyczkami i których nie można wyłączyć z poziomu panelu administratora. Są one idealnym miejscem dla krytycznej logiki biznesowej, definicji Custom Post Types (CPT) czy integracji z systemami zewnętrznymi.
Ograniczenia Standardowego Mechanizmu Mu-plugins
Natywny mechanizm mu-plugins w WordPressie ma poważną wadę: skaner wtyczek nie przeszukuje podkatalogów wewnątrz folderu wp-content/mu-plugins. Oznacza to, że każda wtyczka mu-plugin musi być pojedynczym plikiem PHP umieszczonym bezpośrednio w katalogu głównym mu-plugins. Uniemożliwia to instalację złożonych wtyczek (składających się z wielu plików i katalogów) jako wtyczek wymaganych w sposób zorganizowany.
Rozwiązanie: Bedrock Autoloader
Bedrock rozwiązuje ten problem poprzez implementację Bedrock Autoloader. Jest to specjalny skrypt (bedrock-autoloader.php) umieszczony w katalogu web/app/mu-plugins, który rekurencyjnie skanuje podkatalogi w poszukiwaniu plików wtyczek i ładuje je automatycznie.
Dzięki temu mechanizmowi, możliwe jest instalowanie pełnoprawnych wtyczek z Composera jako mu-plugins. Wystarczy zdefiniować w composer.json instalację danej wtyczki w katalogu web/app/mu-plugins (poprzez installer-paths lub zmianę typu pakietu na wordpress-muplugin).
Korzyści z tego rozwiązania są wielorakie:
- Wymuszona obecność: Krytyczne wtyczki (np. wtyczka do logów, integracja z S3) są zawsze aktywne i użytkownik nie może ich przypadkowo wyłączyć.
- Porządek w kodzie: Możliwość strukturyzowania kodu mu-plugins w podkatalogach zamiast „spaghetti code” w jednym pliku.
- Wersjonowanie: Zarządzanie wersjami mu-plugins poprzez Composer tak samo jak zwykłymi wtyczkami.
Bezpieczeństwo i Hardening Systemu
Bezpieczeństwo jest jednym z filarów, na których zbudowano Bedrocka. Architektura ta implementuje szereg zabezpieczeń, które w standardowym WordPressie wymagają instalacji dodatkowych wtyczek lub ręcznej konfiguracji serwera.
Zmniejszenie Powierzchni Ataku (Attack Surface Reduction)
Poprzez umieszczenie wszystkich plików konfiguracyjnych i zależności poza publicznym katalogiem web, Bedrock drastycznie ogranicza wektory ataku. Wiele automatów atakujących WordPressa szuka pliku wp-config.php w katalogu głównym domeny. W Bedrocku taki plik tam nie istnieje. Nawet w przypadku luki typu „Directory Traversal” w serwerze WWW, która pozwalałaby na odczyt plików, atakujący musiałby znać dokładną strukturę katalogów nadrzędnych, aby dotrzeć do pliku .env.
Blokada Modyfikacji Plików (Immutable Codebase)
W środowiskach produkcyjnych (WP_ENV='production'), Bedrock domyślnie ustawia stałą DISALLOW_FILE_MODS na true. Blokuje to możliwość:
- Instalacji nowych wtyczek i motywów z panelu administratora.
- Aktualizacji wtyczek i motywów z panelu administratora.
- Edycji plików PHP poprzez wbudowany w WordPressa edytor plików.
Jest to kluczowe zabezpieczenie w modelu DevOps. Zmiany w kodzie (w tym aktualizacje wtyczek) powinny być dokonywane w repozytorium, testowane na środowisku stagingowym i wdrażane atomowo na produkcję. Uniemożliwia to sytuację, w której przejęte konto administratora służy do wstrzyknięcia backdoora poprzez edycję pliku motywu lub instalację złośliwej wtyczki.
Bezpieczne Haszowanie Haseł
Chociaż WordPress nadal domyślnie korzysta z algorytmu MD5 do haszowania haseł (dla kompatybilności wstecznej), ekosystem Roots promuje użycie wp_password_bcrypt. Wiele instalacji Bedrocka jest konfigurowanych z użyciem tej biblioteki, co wymusza stosowanie nowoczesnego algorytmu bcrypt, znacznie trudniejszego do złamania metodą brute-force w przypadku wycieku bazy danych.
Instalacja
Jest wiele metod instalacji, ale zostawię to twórcom – robią to najlepiej: https://roots.io/bedrock/docs/installation/
Migracja Legacy do Bedrock
Przeniesienie istniejącej, „tradycyjnej” strony na Bedrock jest procesem wykonalnym, ale wymaga staranności.
| Krok Migracji | Działanie |
| 1. Analiza | Sprawdzenie listy wtyczek i motywów. Identyfikacja wtyczek spoza repozytorium WP.org. |
| 2. Inicjalizacja | Utworzenie czystego projektu Bedrock obok starej strony. |
| 3. Zależności | Instalacja wtyczek w nowym projekcie via Composer (composer require wpackagist-plugin/...). |
| 4. Zasoby | Kopiowanie katalogu wp-content/uploads do web/app/uploads. |
| 5. Kod Własny | Przeniesienie motywu i własnych wtyczek do odpowiednich katalogów w web/app. |
| 6. Baza Danych | Import bazy danych. |
| 7. Search-Replace | Krytyczne: Uruchomienie wp search-replace w celu aktualizacji ścieżek. W Bedrocku ścieżki do plików mogą być inne (np. brak wp-content). |
| 8. Testy | Weryfikacja działania, szczególnie ładowania obrazków i skryptów JS. |
Szczególną uwagę należy zwrócić na wtyczki premium (np. ACF Pro). Jeśli producent nie udostępnia repozytorium Composer, można je zainstalować manualnie w web/app/plugins i dodać do repozytorium (zmieniając .gitignore) lub hostować w prywatnym repozytorium Satis/Private Packagist.
Rozwiązywanie Problemów i Ograniczenia
Problemy z Hostingiem Współdzielonym
Wiele tanich hostingów współdzielonych (Shared Hosting) nie pozwala na zmianę Document Roota na podkatalog. Wymusza to stosowanie obejść w plikach .htaccess, które przekierowują ruch do folderu /web. Jest to rozwiązanie niezalecane, ponieważ potencjalnie eksponuje pliki .env w katalogu nadrzędnym. Bedrock jest przeznaczony dla bardziej profesjonalnych użytkowników, którzy potrafią dobrać samodzielnie hosting. Jeśli potrzebujesz wsparcia, zapraszam Ciebie do nas: IDKCloud.com – pomożemy Ci dobrać usługi tak, byś był zadowolony!
Niekompatybilne Wtyczki
Starsze wtyczki mogą „hardcodować” ścieżkę /wp-content/ w swoich plikach PHP lub JavaScript, zamiast używać funkcji content_url(). W takim przypadku wtyczka nie zadziała w Bedrocku, gdzie katalog nazywa się /app. Rozwiązaniem jest często zgłoszenie problemu autorowi wtyczki lub stworzenie łatki (patcha).
„Biały Ekran” po Deployu
Częstym błędem jest brak zainstalowanych zależności na serwerze. Jeśli wdrożysz tylko pliki z repozytorium Git (bez folderu vendor), strona nie zadziała, ponieważ brakuje autoloada Composera i jądra WP. Należy upewnić się, że proces wdrażania wykonuje composer install.
Podsumowanie
Bedrock stanowi fundamentalną zmianę paradygmatu w ekosystemie WordPress. Przekształca on najpopularniejszy CMS świata z prostego narzędzia blogowego w profesjonalny framework aplikacyjny, zgodny ze standardami inżynierii oprogramowania roku 2026.
Choć próg wejścia jest wyższy niż w standardowym WordPressie – wymagana jest znajomość terminala, Composera i zasad działania serwerów WWW – korzyści w postaci bezpieczeństwa, stabilności, skalowalności i higieny pracy są nie do przecenienia dla profesjonalnych zespołów deweloperskich. Dla agencji interaktywnych i software house’ów, Bedrock (często w połączeniu z motywem Sage i środowiskiem Trellis) stał się de facto standardem tworzenia nowoczesnych stron opartych na WordPressie.
Osobiście już realizowałem projekty oparte o Bedrock w środowisku produkcyjnym, jest to naprawdę przyjemne i wygodne. Korzystając z tego projektu mamy świetną kontrolę nad tym co robimy i kiedy.
Pamiętajmy, że WordPress oraz Bedrock to projekty Open Source, więc warto też znać w jakim zakresie je możemy wykorzystywać. Dowiedz się więcej o licencjach.