Начнём пожалуй, со структуры, в которой всё будет:
docker/ docker-compose.yml .env .env.example .gitignore services database dump .gitignore nginx site.conf php Dockerfile php.ini
А теперь обо всём по порядку:
Файл .gitingore
содержит только одну строчку
/.env
Файл .env.example
в начале проекта такой же, как и
.env
В файле docker-compose.yml
содержится информация
про все наши сервисы:
version: "3.7"services: php: build: args: uname: ${PHP_UNAME} uid: ${PHP_UID} gid: ${PHP_GID} context: ./services/php container_name: ${PROJECT_NAME}_php image: ${PROJECT_NAME}_php restart: unless-stopped working_dir: /var/www/ volumes: - ./services/php/php.ini:/usr/local/etc/php/php.ini - ../:/var/www environment: COMPOSER_MEMORY_LIMIT: 2G XDEBUG_CONFIG: client_host=${XDEBUG_REMOTE_HOST} client_port=${XDEBUG_STORM_PORT} remote_enable=1 PHP_IDE_CONFIG: serverName=${XDEBUG_STORM_SERVER_NAME} networks: - main_network depends_on: - db db: image: mysql:5.6 restart: unless-stopped container_name: ${PROJECT_NAME}_db command: --default-authentication-plugin=mysql_native_password environment: MYSQL_DATABASE: ${DB_DATABASE} MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} MYSQL_PASSWORD: ${DB_PASSWORD} MYSQL_USER: ${DB_USERNAME} ports: - ${DB_LOCAL_PORT}:3306 volumes: - ./services/database/dump:/var/lib/mysql networks: - main_network nginx: image: nginx:1.17-alpine restart: unless-stopped container_name: ${PROJECT_NAME}_nginx ports: - ${NGINX_LOCAL_PORT}:80 volumes: - ../:/var/www - ./services/nginx:/etc/nginx/conf.d networks: - main_network depends_on: - phpnetworks: main_network: driver: bridge name: ${PROJECT_NAME}_main_network ipam: driver: default config: - subnet: ${SUBNET_IP}/${SUBNET_MASK}
Из важного здесь стоит отметить
./services/php/php.ini:/usr/local/etc/php/php.ini
-
наш локальный файл php.ini
(там некоторые конфиги
дебаггера) будет намаплен на тот что внутри контейнера.
XDEBUG_CONFIG
- будет задана переменная окружения
внутри контейнера php
, которую потом будет испльзовать
xdebug вместо значений по-умолчанию. Здесь мы задаем
client_host
- хост, к которому xdebug будет пытаться
подключиться при инициации отладочного соединения. Этот адрес
должен быть адресом машины, на которой ваш PhpStorm прослушивает
входящие отладочные соединения. Получается так, что наша локальная
машина находится в одной подсети с запущеными контейнерами, а её
адресс будет первым в этой подсети. Таким образом, мы всегда можем
знать каким будет адресс нашей машины, и позже зададим это значение
в переменную XDEBUG_REMOTE_HOST
. В
CLIENT_PORT
нужно будет задать порт, установленный на
прослушивание в IDE (9003). XDEBUG_STORM_SERVER_NAME
-
имя сервера, который мы создадим в IDE позже. Этот параметр нужен,
чтобы сообщить PhpStorm, как сопоставлять пути при подключении с
докера (ведь у вас же открыты локальные файлы в редакторе, а код
работает на удалённых; хотя при испльзовании volumes это не совсем
так).
Вот, как выглядит файл окружения .env
:
PROJECT_NAME=my_projectDB_DATABASE=my_project_dbDB_USERNAME=my_projectDB_PASSWORD=p@$$w0rdDB_ROOT_PASSWORD=toorPHP_UNAME=devPHP_UID=1000PHP_GID=1000DB_LOCAL_PORT=3377NGINX_LOCAL_PORT=8077XDEBUG_STORM_SERVER_NAME=DockerXDEBUG_REMOTE_HOST=192.168.227.1XDEBUG_STORM_PORT=9003SUBNET_IP=192.168.227.0SUBNET_MASK=28
На счёт подсети для проекта, то здесь мы задали
192.168.227.0
с маской 28, то-есть для всех устройств
остаётся 32 - 28 = 4 бита
, что равносильно 2 **
4 - 1 = 15 контейнеров
. Не 16 потому что в подсеть входит
также наша локальная машина, которая, кстати, будет иметь адресс
192.168.227.1
. Именно это значение мы задали в
переменную XDEBUG_REMOTE_HOST
.
Настройки веб-сервера site.conf
:
server { listen 80; server_name 127.0.0.1 localhost; client_max_body_size 5m; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; root /var/www/public; index index.php; location / { try_files $uri $uri/ /index.php?$query_string; gzip_static on; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; }}
В нашем Dockerfile (тот что для php) нужно не забыть установить и включить xdebug. Для этого добавляем 2 строчки:
RUN pecl install xdebugRUN docker-php-ext-enable xdebug
Стоит отметить, что будет испльзована последняя (то-есть 3) версия (есть различия в конфигурации по сравнению с 2).
Полный Dockerfile
:
FROM php:7.4-fpm# Arguments defined in docker-compose.ymlARG unameARG gidARG uid# Install system dependenciesRUN apt-get update \ && apt-get install -y \ git \ curl \ dpkg-dev \ libpng-dev \ libjpeg-dev \ libonig-dev \ libxml2-dev \ libpq-dev \ libzip-dev \ zip \ unzip \ cronRUN pecl install xdebugRUN docker-php-ext-enable xdebugRUN docker-php-ext-configure gd \ --enable-gd \ --with-jpegADD ./php.ini /usr/local/etc/php/php.ini# Clear cacheRUN apt-get clean && rm -rf /var/lib/apt/lists/*# Install PHP extensionsRUN docker-php-ext-install pdo pdo_mysql pdo_pgsql pgsql mbstring exif pcntl bcmath gd sockets zip# Get latest ComposerCOPY --from=composer:latest /usr/bin/composer /usr/bin/composer# Create system user to run Composer and Artisan CommandsRUN groupadd --gid $gid $unameRUN useradd -G www-data,root -s /bin/bash --uid $uid --gid $gid $unameRUN mkdir -p /home/$uname/.composer && \ chown -R $uname:$uname /home/$uname# Set working directoryWORKDIR /var/wwwUSER $uname# Expose port 9000 and start php-fpm serverEXPOSE 9000CMD ["php-fpm"]
Также, зададим некоторые параметры исплнения в
php.ini
:
max_execution_time=1000max_input_time=1000xdebug.mode=debugxdebug.log="/var/www/xdebug.log"xdebug.remote_enable=1
Запустим наше приложение:
docker-compose up -d
И дальше пойдём в PhpStorm для настройки:
Создадим сервер с названием Docker и cделаем маппинг локального
корня проекта (/var/www/quizzy.loc
) на путь, по
которому он лежит в докере (/var/www
):

Дальше, нам нужно будет настроить использование интерпретатора php из докера:



Теперь можем перейти в подпункт "Debug" и настроить порт на котором запускать:

Проверим, работает ли Xdebug:

Теперь можем поставить брейкпоинт в нашем коде и начать прослушивание входящих подключений:

Переходим в наш любимый браузер Firefox, устанавливаем и включаем плагин на нужной странице:

Перезагружаем страницу, и в PhpStrom должен поймать подключение:
