DDEV świetnie sprawdza się na co dzień, ale co jeśli potrzebujesz niestandardowej konfiguracji, której DDEV nie obsługuje? Albo chcesz rozumieć co dzieje się pod spodem? Pokazuję jak zbudować środowisko PHP od zera z czystym Dockerem i docker-compose – nginx, PHP-FPM, MySQL i Redis bez żadnych narzędzi pośrednich.
Struktura projektu
project/
docker/
nginx/
default.conf
php/
Dockerfile
php.ini
src/ <- kod aplikacji
docker-compose.yml
Dockerfile dla PHP-FPM
Bazujemy na oficjalnym obrazie PHP-FPM i doinstalowujemy rozszerzenia potrzebne przy Magento 2:
FROM php:7.4-fpm
# Zależności systemowe
RUN apt-get update && apt-get install -y \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
libzip-dev \
libicu-dev \
libxslt-dev \
libonig-dev \
git \
unzip \
&& rm -rf /var/lib/apt/lists/*
# Rozszerzenia PHP
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) \
gd \
pdo_mysql \
zip \
intl \
xsl \
soap \
bcmath \
sockets \
opcache
# Xdebug
RUN pecl install xdebug-2.9.8 \
&& docker-php-ext-enable xdebug
# Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
# Uprawnienia
RUN usermod -u 1000 www-data
USER www-data
Konfiguracja PHP – php.ini
[PHP] memory_limit = 2G max_execution_time = 600 upload_max_filesize = 64M post_max_size = 64M date.timezone = Europe/Warsaw [opcache] opcache.enable = 1 opcache.memory_consumption = 256 opcache.max_accelerated_files = 60000 opcache.validate_timestamps = 1 [xdebug] xdebug.mode = debug xdebug.client_host = host.docker.internal xdebug.client_port = 9003 xdebug.start_with_request = no xdebug.idekey = PHPSTORM
Konfiguracja nginx
upstream fastcgi_backend {
server php:9000;
}
server {
listen 80;
server_name localhost;
root /var/www/html/pub;
index index.php;
autoindex off;
charset UTF-8;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ ^/index\.php$ {
fastcgi_pass fastcgi_backend;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_param MAGE_MODE developer;
}
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
expires 30d;
}
location ~ /\. {
deny all;
}
}
docker-compose.yml – składamy całość
version: '3.8'
services:
nginx:
image: nginx:1.18-alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./src:/var/www/html
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
php:
build:
context: .
dockerfile: docker/php/Dockerfile
volumes:
- ./src:/var/www/html
- ./docker/php/php.ini:/usr/local/etc/php/conf.d/custom.ini
environment:
- XDEBUG_MODE=off
depends_on:
- db
- redis
db:
image: mariadb:10.4
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: magento
MYSQL_USER: magento
MYSQL_PASSWORD: magento
volumes:
- db_data:/var/lib/mysql
ports:
- "3306:3306"
redis:
image: redis:6-alpine
ports:
- "6379:6379"
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.6.2
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ports:
- "9200:9200"
volumes:
- es_data:/usr/share/elasticsearch/data
volumes:
db_data:
es_data:
Uruchomienie i podstawowe komendy
# Zbuduj obrazy i uruchom docker-compose up -d --build # Wejdź do kontenera PHP docker-compose exec php bash # Wykonaj komendę Magento docker-compose exec php bin/magento setup:upgrade # Włącz Xdebug na czas sesji docker-compose exec php bash -c "XDEBUG_MODE=debug php bin/magento ..." # Logi nginx docker-compose logs -f nginx # Zatrzymaj wszystko docker-compose down # Zatrzymaj i usuń volumeny (czysty reset) docker-compose down -v
Xdebug 3.x i PHPStorm – konfiguracja
Xdebug 3.x zmienił nazwy dyrektyw konfiguracyjnych względem 2.x. Zamiast remote_enable mamy teraz xdebug.mode. W PHPStorm ustaw serwer PHP z path mappingiem między lokalnym katalogiem ./src a /var/www/html w kontenerze. Bez tego mapowania breakpointy nie będą trafiać w odpowiednie linie.
Kiedy czysty Docker zamiast DDEV?
Czysty Docker ma sens gdy: potrzebujesz niestandardowych wersji serwisów których DDEV nie wspiera, budujesz środowisko CI/CD które ma być identyczne z lokalnym, chcesz pełnej kontroli nad siecią kontenerów, albo projekt ma specyficzne wymagania infrastrukturalne (np. własny reverse proxy, kilka domen na jednym stosie).
Podsumowanie
Czysty Docker wymaga więcej pracy konfiguracyjnej niż DDEV, ale daje pełną kontrolę i głębsze rozumienie środowiska. Warto przejść przez ten proces przynajmniej raz - wtedy abstrakcja DDEV przestaje być czarną skrzynką i staje się świadomym wyborem wygody.
