Rozwój WordPress przerósł przesyłanie plików przez FTP i panele hostingu współdzielonego. W 2026 roku profesjonalne zespoły traktują WordPress jak każdy inny projekt programistyczny, z wersjonowanymi zależnościami, konteneryzowanymi środowiskami i zautomatyzowanymi pipeline wdrożeniowymi. Jeśli nadal edytujesz pliki bezpośrednio na serwerze produkcyjnym, ten przewodnik zmieni sposób Twojej pracy.
Ten poradnik obejmuje dwa komplementarne podejścia do nowoczesnego rozwoju WordPress: Docker Compose do powtarzalnych środowisk serwerowych i Composer z Bedrock do zarządzania zależnościami. Otrzymasz kompletne, gotowe do skopiowania pliki konfiguracyjne, konfigurację Xdebug do prawidłowego debugowania PHP oraz przepływ wdrożeniowy, który bezpiecznie przenosi Twój kod z maszyny lokalnej na produkcję.
Dlaczego tradycyjna konfiguracja WordPress Cię ogranicza
Klasyczne podejście polegające na pobraniu pliku ZIP z wordpress.org i przesłaniu go przez FTP tworzy kilka problemów, które narastają z czasem:
- Rozbieżność środowisk - Twoja lokalna konfiguracja MAMP lub XAMPP nigdy nie odpowiada dokładnie serwerowi produkcyjnemu, co prowadzi do błędów typu “u mnie działa”.
- Brak śledzenia zależności - wtyczki i motywy są pobierane i aktualizowane ręcznie, co uniemożliwia odtworzenie dokładnie tej samej strony na innej maszynie.
- Brak kontroli wersji dla rdzenia - pliki rdzenia WordPress znajdują się w Twoim repozytorium (lub gorzej, nie są w ogóle śledzone), mieszając kod aplikacji z kodem frameworka.
- Ręczne wdrożenia - kopiowanie plików przez FTP jest podatne na błędy i nie zapewnia mechanizmu cofania zmian.
Docker i Composer rozwiązują każdy z tych problemów systematycznie.
Konfiguracja WordPress z Docker Compose
Docker Compose pozwala zdefiniować cały stos serwerowy w jednym pliku YAML. Każdy deweloper w zespole otrzymuje dokładnie tę samą wersję PHP, wersję MySQL i konfigurację serwera, uruchamiając jedno polecenie.
Wymagania wstępne
Zainstaluj Docker Desktop dla swojego systemu operacyjnego. Docker Desktop zawiera zarówno silnik Docker, jak i wtyczkę CLI docker compose. Zweryfikuj instalację:
docker --version
docker compose version
Struktura projektu
Utwórz czysty katalog projektu:
mkdir wordpress-docker && cd wordpress-docker
mkdir -p wp-content/themes wp-content/plugins wp-content/uploads
Kompletny docker-compose.yml
Utwórz plik docker-compose.yml w katalogu głównym projektu:
version: "3.9"
services:
db:
image: mysql:8.0
container_name: wp_mysql
restart: unless-stopped
environment:
MYSQL_DATABASE: ${DB_NAME:-wordpress}
MYSQL_USER: ${DB_USER:-wpuser}
MYSQL_PASSWORD: ${DB_PASSWORD:-wppassword}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-rootpassword}
volumes:
- db_data:/var/lib/mysql
ports:
- "3306:3306"
networks:
- wp_network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
wordpress:
image: wordpress:6.7-php8.3-apache
container_name: wp_app
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: ${DB_NAME:-wordpress}
WORDPRESS_DB_USER: ${DB_USER:-wpuser}
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD:-wppassword}
WORDPRESS_DEBUG: ${WP_DEBUG:-1}
WORDPRESS_CONFIG_EXTRA: |
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
define('SCRIPT_DEBUG', true);
define('DISALLOW_FILE_EDIT', true);
volumes:
- ./wp-content/themes:/var/www/html/wp-content/themes
- ./wp-content/plugins:/var/www/html/wp-content/plugins
- ./wp-content/uploads:/var/www/html/wp-content/uploads
- ./php-custom.ini:/usr/local/etc/php/conf.d/custom.ini
ports:
- "8080:80"
networks:
- wp_network
phpmyadmin:
image: phpmyadmin:5
container_name: wp_phpmyadmin
restart: unless-stopped
depends_on:
- db
environment:
PMA_HOST: db
PMA_PORT: 3306
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-rootpassword}
ports:
- "8081:80"
networks:
- wp_network
mailhog:
image: mailhog/mailhog:latest
container_name: wp_mailhog
ports:
- "1025:1025"
- "8025:8025"
networks:
- wp_network
volumes:
db_data:
networks:
wp_network:
driver: bridge
Ta konfiguracja daje cztery usługi:
- MySQL 8.0 z kontrolą stanu zdrowia, dzięki czemu WordPress czeka na gotowość bazy danych przed uruchomieniem.
- WordPress 6.7 na PHP 8.3 z Apache, montujący tylko Twoje własne motywy, wtyczki i przesłane pliki.
- phpMyAdmin do wizualnego zarządzania bazą danych pod adresem
http://localhost:8081. - MailHog do przechwytywania wychodzących e-maili podczas rozwoju pod adresem
http://localhost:8025.
Zmienne środowiskowe z .env
Utwórz plik .env w katalogu głównym projektu:
# Baza danych
DB_NAME=wordpress
DB_USER=wpuser
DB_PASSWORD=secure_local_password_2026
DB_ROOT_PASSWORD=secure_root_password_2026
# WordPress
WP_DEBUG=1
# Strona
SITE_URL=http://localhost:8080
Docker Compose automatycznie odczytuje pliki .env z katalogu projektu. Dodaj .env do .gitignore natychmiast i zamiast tego commituj szablon .env.example.
Własna konfiguracja PHP
Utwórz php-custom.ini z przyjaznymi dla developmentu ustawieniami PHP:
upload_max_filesize = 128M
post_max_size = 128M
memory_limit = 512M
max_execution_time = 300
max_input_vars = 3000
display_errors = On
error_reporting = E_ALL
Uruchamianie środowiska
docker compose up -d
Otwórz http://localhost:8080 i dokończ instalację WordPress. Katalogi motywów i wtyczek są montowane z maszyny hosta, więc wszelkie zmiany wprowadzone w edytorze pojawiają się natychmiast w uruchomionej instancji WordPress.
Przydatne polecenia Docker do codzieńnej pracy
# Wyświetl logi że wszystkich kontenerów
docker compose logs -f
# Wyświetl logi tylko z WordPress
docker compose logs -f wordpress
# Otwórz powłokę wewnątrz kontenera WordPress
docker compose exec wordpress bash
# Uruchom polecenia WP-CLI wewnątrz kontenera
docker compose exec wordpress wp plugin list --allow-root
# Zatrzymaj wszystkie kontenery (zachowuje dane)
docker compose stop
# Zatrzymaj i usuń kontenery (zachowuje dane wolumenów)
docker compose down
# Pełny reset łącznie z bazą danych
docker compose down -v
WordPress oparty na Composer z Bedrock
Podczas gdy Docker obsługuje środowisko serwerowe, Bedrock od Roots restrukturyzuje sam WordPress w prawidłowo zarządzaną przez Composer aplikację. Bedrock traktuje rdzeń WordPress jako zależność, a nie jako katalog główny projektu, co zmienia wszystko w sposobie zarządzania i wdrażania WordPress.
Dlaczego Bedrock ma znaczenie
Standardowy WordPress miesza kod aplikacji (Twój motyw, wtyczki) z kodem frameworka (wp-admin, wp-includes) w tym samym katalogu. Bedrock rozdziela te warstwy:
project-root/
config/ # Konfiguracja specyficzna dla środowiska
application.php
environments/
development.php
staging.php
production.php
web/ # Katalog główny dokumentów (publiczny)
app/ # Odpowiednik wp-content
themes/
plugins/
uploads/
wp/ # Rdzeń WordPress (zarządzany przez Composer)
wp-config.php # Minimalny loader
vendor/ # Zależności Composer
.env # Zmienne środowiskowe
composer.json # Manifest zależności
Rdzeń WordPress znajduje się w web/wp/ i nigdy nie jest modyfikowany. Twój własny kod znajduje się w web/app/. Katalog vendor/ i web/wp/ są oba w gitignore, ponieważ Composer odtwarza je z composer.json.
Instalacja Bedrock
composer create-project roots/bedrock my-wordpress-project
cd my-wordpress-project
Struktura composer.json
composer.json Bedrock zarządza rdzeniem WordPress, wtyczkami i motywami jako pakietami:
{
"name": "your-agency/client-project",
"type": "project",
"license": "MIT",
"description": "WordPress project managed with Bedrock and Composer",
"require": {
"php": ">=8.1",
"composer/installers": "^2.3",
"vlucas/phpdotenv": "^5.6",
"oscarotero/env": "^2.1",
"roots/bedrock-autoloader": "^1.0",
"roots/bedrock-disallow-indexing": "^2.0",
"roots/wordpress": "6.7.*",
"roots/wp-config": "1.0.0",
"roots/wp-password-bcrypt": "1.1.0",
"wpackagist-plugin/wordpress-seo": "^23.0",
"wpackagist-plugin/wp-super-cache": "^1.12",
"wpackagist-plugin/wordfence": "^7.11"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.10",
"roave/security-advisories": "dev-latest"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"allow-plugins": {
"composer/installers": true,
"roots/wordpress-core-installer": true
}
},
"repositories": [
{
"type": "composer",
"url": "https://wpackagist.org",
"only": [
"wpackagist-plugin/*",
"wpackagist-theme/*"
]
}
],
"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"
}
}
Kluczowa informacja: WordPress Packagist mirroruje całe repozytorium wtyczek i motywów WordPress.org jako pakiety Composer. Dodanie wtyczki jest tak proste jak:
composer require wpackagist-plugin/advanced-custom-fields
Usunięcie jest równie czyste:
composer remove wpackagist-plugin/advanced-custom-fields
Konfiguracja środowiska Bedrock
Bedrock używa plików .env zamiast twardego kodowania wartości w wp-config.php:
# Plik .env dla Bedrock
DB_NAME=wordpress
DB_USER=wpuser
DB_PASSWORD=secure_local_password_2026
DB_HOST=db:3306
DB_PREFIX=wp_
WP_ENV=development
WP_HOME=http://localhost:8080
WP_SITEURL=${WP_HOME}/wp
# Wygeneruj te klucze na https://roots.io/salts.html
AUTH_KEY='generate-unique-key-here'
SECURE_AUTH_KEY='generate-unique-key-here'
LOGGED_IN_KEY='generate-unique-key-here'
NONCE_KEY='generate-unique-key-here'
AUTH_SALT='generate-unique-salt-here'
SECURE_AUTH_SALT='generate-unique-salt-here'
LOGGED_IN_SALT='generate-unique-salt-here'
NONCE_SALT='generate-unique-salt-here'
Każde środowisko (development, staging, produkcja) ma własny plik .env na swoim serwerze. Ten sam kod działa wszędzie, a zachowanie jest kontrolowane wyłącznie przez zmienne środowiskowe.
Łączenie Docker i Bedrock
Prawdziwa moc pojawia się przy uruchamianiu Bedrock wewnątrz Docker. Zmodyfikuj docker-compose.yml, aby zamontować projekt Bedrock zamiast domyślnego obrazu WordPress:
services:
wordpress:
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/var/www/html
environment:
- WP_ENV=development
Z własnym Dockerfile:
FROM php:8.3-apache
RUN apt-get update && apt-get install -y \
libzip-dev \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
libicu-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install \
mysqli \
pdo_mysql \
zip \
gd \
intl \
opcache
RUN a2enmod rewrite
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
ENV APACHE_DOCUMENT_ROOT /var/www/html/web
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' \
/etc/apache2/sites-available/*.conf \
/etc/apache2/apache2.conf
WORKDIR /var/www/html
To daje w pełni skonteneryzowane środowisko Bedrock, w którym composer install uruchamia się wewnątrz kontenera, a katalog główny dokumentów wskazuje na katalog web/ Bedrock.
Konfiguracja Xdebug do debugowania PHP
Debugowanie krokowe zastępuje var_dump i error_log właściwym debuggerem, który pozwala wstrzymać wykonanie, sprawdzić zmienne i przejść przez kod linia po linii.
Dodawanie Xdebug do kontenera Docker
Utwórz plik xdebug.ini:
[xdebug]
zend_extension=xdebug
xdebug.mode=debug,develop
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.discover_client_host=0
xdebug.log=/tmp/xdebug.log
xdebug.idekey=VSCODE
Dodaj instalację Xdebug do Dockerfile:
RUN pecl install xdebug-3.3.2 \
&& docker-php-ext-enable xdebug
COPY xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
Konfiguracja VS Code
Utwórz .vscode/launch.json w katalogu głównym projektu:
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for Xdebug (Docker)",
"type": "php",
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/html": "${workspaceFolder}"
},
"log": true
}
]
}
Zainstaluj rozszerzenie PHP Debug od Xdebug w VS Code, ustaw breakpoint w dowolnym pliku PHP, naciśnij F5, aby rozpocząć nasłuchiwanie, i przeładuj stronę WordPress. Debugger zatrzyma się na Twoim breakpoincie.
Konfiguracja PhpStorm
PhpStorm obsługuje połączenia Xdebug z Docker natywnie:
- Przejdź do Settings > PHP > Debug i zweryfikuj, że port 9003 jest ustawiony.
- Przejdź do Settings > PHP > Servers, dodaj nowy serwer z
localhostna porcie8080i skonfiguruj mapowanie ścieżek z/var/www/htmldo katalogu głównego projektu. - Kliknij przycisk Start Listening for PHP Debug Connections na pasku narzędzi.
Przepływ wdrożeniowy: od lokalnego do staging do produkcji
Profesjonalny pipeline wdrożeniowy zapewnia, że zmiany w kodzie przepływają przewidywalnie od developmentu do produkcji bez ręcznego kopiowania plików.
Model trzech środowisk
- Lokalne (Docker) - gdzie piszesz i testujesz kod.
- Staging - serwer odzwierciedlający produkcję do końcowych testów.
- Produkcja - strona na żywo.
Wdrożenie oparte na Git z GitHub Actions
Twoje repozytorium powinno zawierać kod motywu, wtyczki i konfigurację Bedrock. Nie powinno zawierać rdzenia WordPress, katalogu vendor/ ani uploads/.
Przykładowy .github/workflows/deploy.yml:
name: Deploy to staging
on:
push:
branches: [staging]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.3"
- name: Install dependencies
run: composer install --no-dev --optimize-autoloader
- name: Run code quality checks
run: vendor/bin/phpcs --standard=WordPress web/app/themes/
- name: Deploy via rsync
uses: burnett01/rsync-deployments@7.0
with:
switches: -avz --delete --exclude='.env' --exclude='web/app/uploads/'
path: ./
remote_path: /var/www/staging.example.com/
remote_host: ${{ secrets.STAGING_HOST }}
remote_user: ${{ secrets.STAGING_USER }}
remote_key: ${{ secrets.STAGING_SSH_KEY }}
Synchronizacja bazy danych i przesłanych plików
Kod jest wdrażany przez Git, ale bazy danych i pliki multimedialne wymagają oddzielnej obsługi:
# Eksport bazy danych produkcyjnej
wp db export production-backup.sql --ssh=user@production
# Import na staging
wp db import production-backup.sql --ssh=user@staging
# Zamiana adresów URL
wp search-replace 'https://example.com' 'https://staging.example.com' --ssh=user@staging
# Synchronizacja plików z produkcji na staging
rsync -avz user@production:/var/www/html/web/app/uploads/ \
user@staging:/var/www/html/web/app/uploads/
Do lokalnego developmentu używaj poleceń WP-CLI wp db export i wp db import przez Docker:
docker compose exec wordpress wp db export /tmp/backup.sql --allow-root
docker cp wp_app:/tmp/backup.sql ./backups/
Porównanie: Docker vs Composer vs LocalWP vs MAMP
| Funkcja | Docker Compose | Composer (Bedrock) | LocalWP | MAMP/XAMPP |
|---|---|---|---|---|
| Powtarzalność środowiska | Doskonała - zdefiniowana w kodzie | Nie dotyczy (tylko zarządzanie kodem) | Ograniczona - per maszyna | Ograniczona - per maszyna |
| Spójność zespołowa | Pełna zgodność między maszynami | Pełna zgodność dla zależności | Ręczna konfiguracja per deweloper | Ręczna konfiguracja per deweloper |
| Kontrola wersji PHP | Dokładna wersja w Dockerfile | Wymaga oddzielnego serwera | Przełączalna per strona | Ustawienie globalne |
| Zarządzanie zależnościami | Nie dotyczy (tylko serwer) | Doskonałe - composer.lock | Brak | Brak |
| Zgodność z produkcją | Dokładne odwzorowanie produkcji | Zgodność zależności produkcyjnych | Przybliżona | Przybliżona |
| Krzywa uczenia | Umiarkowana - wymaga komfortu z CLI | Umiarkowana - znajomość ekosystemu PHP | Niska - oparta na GUI | Niska - oparta na GUI |
| Integracja CI/CD | Natywna | Natywna | Brak | Brak |
| Izolacja wielu projektów | Pełna izolacja kontenerów | Oddzielna per projekt | Oddzielna per strona | Współdzielony serwer |
| Własne konfiguracje serwera | Pełna kontrola | Nie dotyczy | Ograniczone | Ograniczone |
| Szybkość uruchamiania | Umiarkowana (pierwszy pull jest wolny) | Szybka (composer install) | Szybka | Szybka |
Kluczowy wniosek: Docker i Composer są komplementarne, nie konkurencyjne. Docker zastępuje MAMP/XAMPP jako środowisko serwerowe, a Composer zastępuje ręczne zarządzanie wtyczkami/motywami. LocalWP pozostaje dobrym wyborem do szybkiego prototypowania, ale brakuje mu powtarzalności i integracji CI/CD, których potrzebują profesjonalne zespoły.
Wskazówki wydajnościowe dla Docker na macOS
Docker na macOS historycznie cierpiał z powodu wolnej wydajności systemu plików wynikającej z warstwy wirtualizacji. W 2026 roku Docker Desktop domyślnie używa VirtioFS, co dramatycznie poprawia prędkość I/O. Jeśli nadal doświadczasz spowolnień:
- Sprawdź, czy VirtioFS jest włączony w Docker Desktop > Settings > General.
- Ogranicz montowane wolumeny tylko do tego, czego potrzebujesz (motywy, wtyczki, przesłane pliki), a nie całej instalacji WordPress.
- Użyj wbudowanych dyrektyw cachowania Docker, jeśli to potrzebne:
volumes: - ./wp-content:/var/www/html/wp-content:cached. - Przydziel wystarczające zasoby w Docker Desktop > Settings > Resources (co najmniej 4 GB RAM i 2 CPU).
Kwestie bezpieczeństwa w środowisku lokalnym
Nawet w środowiskach lokalnych nawyki bezpieczeństwa mają znaczenie, ponieważ konfiguracje często wyciekają na produkcję:
- Nigdy nie commituj plików
.envdo Git. Używaj.env.examplejako szablonu. - Używaj silnych, unikalnych haseł w swoim
.envnawet lokalnie, aby nigdy przypadkowo nie wdrożyć słabych danych dostępowych. - Utrzymuj
DISALLOW_FILE_EDITustawione natruewe wszystkich środowiskach. - Regularnie uruchamiaj
composer audit, aby sprawdzać znane podatności w zależnościach. - Przypinaj konkretne wersje w
composer.jsondla wdrożeń produkcyjnych zamiast używania luźnych ograniczeń wersji.
Rozwiązywanie typowych problemów
Kontener MySQL natychmiast się zamyka
Sprawdź logi za pomocą docker compose logs db. Najczęstszą przyczyną jest istniejący wolumen z niekompatybilnymi danymi. Uruchom docker compose down -v, aby usunąć wolumeny i zacząć od nowa.
WordPress nie może połączyć się z bazą danych
Sprawdź, czy wartość WORDPRESS_DB_HOST odpowiada nazwie usługi w docker-compose.yml (zazwyczaj db:3306). Upewnij się, że kontener bazy danych jest zdrowy przed uruchomieniem WordPress, korzystając z warunku depends_on pokazanego w konfiguracji powyżej.
Xdebug się nie łączy
Potwierdź, że host.docker.internal rozwiązuje się poprawnie wewnątrz kontenera. Na Linux może być konieczne dodanie extra_hosts: - "host.docker.internal:host-gateway" do definicji usługi WordPress.
Błędy uprawnień do plików
Jeśli WordPress nie może zapisywać do wp-content/uploads, dostosuj uprawnienia wewnątrz kontenera:
docker compose exec wordpress chown -R www-data:www-data /var/www/html/wp-content/uploads
Kolejne kroki dla Twojego przepływu pracy
Gdy masz już Docker i Composer działające, rozważ te dodatki, aby jeszcze bardziej sprofesjonalizować swoją konfigurację:
- WP-CLI jako zależność Composer do skryptowego zarządzania WordPress.
- PHPStan lub Psalm do statycznej analizy kodu PHP motywów i wtyczek.
- GitHub Actions lub GitLab CI do automatycznego testowania przy każdym pull request.
- Redis lub Memcached jako dodatkowa usługa Docker do cachowania obiektów podczas developmentu.
- Traefik lub Nginx Proxy do zarządzania wieloma lokalnymi projektami WordPress z własnymi domenami zamiast numerów portów.
Nowoczesna inżynieria WordPress oznacza traktowanie strony jak produktu programistycznego, z powtarzalnymi buildami, automatycznym testowaniem i bezpiecznymi wdrożeniami. Narzędzia omówione w tym przewodniku, Docker Compose do środowisk i Composer z Bedrock do zarządzania zależnościami, stanowią fundament, którego potrzebuje każdy poważny zespół WordPress w 2026 roku.
W wppoland.com budujemy i utrzymujemy projekty WordPress używając dokładnie tych przepływów pracy. Jeśli Twój zespół potrzebuje pomocy w modernizacji procesu rozwoju WordPress, konfiguracji pipeline CI/CD lub migracji że starszych konfiguracji do skonteneryzowanych środowisk, nasz zespół inżynierów jest dostępny do konsultacji i wdrożeń. Wycena jest zawsze indywidualna i zależy od zakresu projektu.


