Если вам доводилось работать с Magento 2 на Docker, вы, вероятно, сталкивались со сборкой «Mark Shust's Docker setup» (https://github.com/markshust/docker-magento). Я использовал её в нескольких проектах, и обычно она работает железобетонно.

Недавно у моей системы возникли проблемы с памятью, поэтому я решил провести генеральную уборку: очистил неиспользуемые Docker-образы и тома, а затем снова поднял всё с помощью:

docker compose up -d

Именно тогда я столкнулся со странной проблемой, на решение которой ушло гораздо больше времени, чем мне хотелось бы признавать. Мое окружение уже прекрасно работало на PHP 8.3, но внезапно сайт вообще перестал загружаться. Каждый запрос возвращал ошибку 502 Bad Gateway.

Если вы новичок в Docker или администрировании серверов, ошибка 502 может показаться непреодолимой стеной. Но 502 просто означает, что один сервер (выступающий в роли прокси) получил недействительный ответ — или не получил его вовсе — от вышестоящего (upstream) сервера, к которому он пытается обратиться.

В нашем стеке Magento на базе Docker прокси-сервером является Nginx, а upstream-сервером — PHP-FPM.

Вот как именно следует подходить к отладке этой проблемы, шаг за шагом.

---

Шаг 1: Проверьте лог-файлы прокси Nginx на наличие ошибок 502

Поскольку ошибка 502 отдается Nginx, сам Nginx точно знает, почему он её выдал. Первое, что нужно сделать — проверить логи ошибок контейнера Nginx:

# В зависимости от вашей настройки, имя контейнера может быть nginx, app или web.
docker compose logs app

В своих логах я обнаружил следующую критическую ошибку:

[crit] 30#30: *8 connect() to unix:/sock/docker.sock failed (2: No such file or directory) while connecting to upstream

Эта единственная строка дает нам три важнейшие подсказки:

1. "connect() ... failed"
Nginx пытается передать запрос следующему сервису в цепочке.

2. "unix:/sock/docker.sock"
Nginx настроен на взаимодействие с PHP через файл сокета Unix, расположенный по пути "/sock/docker.sock" (вместо сетевого TCP-порта вроде "9000").

3. "No such file or directory"
Файл сокета просто не существует.

---

Шаг 2: Проверьте контейнер PHP-FPM для Magento

Nginx жалуется, что не может достучаться до PHP. Следующий логичный вопрос:

Работает ли PHP вообще? Не упал ли он?

Давайте проверим логи PHP-контейнера:

docker compose logs phpfpm

Вот что я увидел:

[11-Jun-2026 10:02:24] NOTICE: fpm is running, pid 1
[11-Jun-2026 10:02:24] NOTICE: ready to handle connections

PHP чувствовал себя прекрасно и ждал запросов. Он не падал.

---

Шаг 3: Исследование сокет-соединения Nginx и PHP-FPM

Мы знаем, что Nginx ищет конкретный файл по пути "/sock/docker.sock".

Мы знаем, что PHP запущен.

В этой конфигурации Docker каталог "/sock" представляет собой общий Docker-том, смонтированный как в контейнер Nginx, так и в контейнер PHP для обеспечения связи между ними.

Я решил зайти внутрь PHP-контейнера, чтобы посмотреть, что на самом деле находится в этом общем каталоге:

docker exec -it <php-container-name> ls -la /sock

Вместо файла "docker.sock", который так отчаянно искал Nginx, я увидел следующее:

srw-rw---- 1 app app 0 Jun 11 10:39 phpfpm.sock

---

Шаг 4: Выявление несоответствия сокетов

Это был момент озарения («Эврика!»).

- Nginx был жестко запрограммирован на поиск "docker.sock".
- PHP был настроен на создание и прослушивание "phpfpm.sock".

Они физически не могли связаться друг с другом, потому что у них не было согласия насчет имени файла.

Но почему два сервиса из одного и того же готового шаблона расходятся в столь фундаментальном вопросе?

---

Странность: почему одно окружение работало

Еще больше запутывало то, что у меня была другая машина, на которой крутился точно такой же проект.

Тот же кодовая база.

Тот же файл "docker-compose.yml".

Та же версия PHP.

И это окружение работало идеально.

Когда я проверил каталог "/sock" на рабочей машине, я обнаружил там только:

docker.sock

Теперь я был запутан еще больше.

Почему на одной машине был "docker.sock", а на другой — нет?

---

Поиск первопричины: несовпадение версий Docker-образов

Покопавшись в репозитории "docker-magento" (https://github.com/markshust/docker-magento) и сравнив версии образов, я наконец заметил одну важную вещь.

В моем окружении использовались:

PHP: markoshust/magento-php:8.3-fpm
Nginx: markoshust/magento-nginx:1.18-7

Образ PHP был относительно новым.

Образ Nginx отставал на несколько версий.

Это несоответствие версий и оказалось сутью всей проблемы.

---

Что изменилось в Docker-образах Magento?

В новых версиях образов docker-magento была внедрена специализированная архитектура Xdebug.

Вместо прогона всех запросов через единственный процесс PHP-FPM, стек теперь использует раздельные контейнеры PHP-FPM для обычных запросов и для запросов с включенным Xdebug — контейнеры "phpfpm" и "phpfpm-xdebug", работающие бок о бок.

Nginx осуществляет маршрутизацию между ними на основе куки (cookie).

Из-за этого архитектурного изменения изменились и имена сокетов.

В старых образах использовалось:

/sock/docker.sock

В новых образах используется:

/sock/phpfpm.sock
/sock/phpfpm-xdebug.sock

Мой контейнер с PHP 8.3 создавал новые файлы сокетов, в то время как старый контейнер Nginx был по-прежнему жестко настроен на поиск "docker.sock".

Как только я это понял, ошибка 502 наконец обрела смысл.

---

Почему другое окружение работало со старыми томами?

Ответ крылся в Docker-томах.

Каталог сокетов хранится в общем томе:

sockdata:/sock

Docker-тома переживают пересборку контейнеров и обновление образов.

В какой-то момент рабочее окружение было развернуто на старых образах, которые создавали "docker.sock".

Позже образ PHP был обновлен и начал создавать "phpfpm.sock", но старый файл "docker.sock" остался лежать в томе.

Этот старый файл фактически маскировал несоответствие версий и создавал видимость того, что окружение здорово и работоспособно.

Поскольку из-за проблем с памятью я только что очистил (pruned) свои Docker-тома, моя чистая установка стерла тот исторический файл "docker.sock".

Когда устаревший файл исчез, несоответствие между моим старым образом Nginx и новым образом PHP стало сразу же очевидным.

---

Как исправить ошибку 502 в Docker с Magento 2

Правильным решением было не ручное переименование сокетов и не создание символьных ссылок.

Решение заключалось в том, чтобы убедиться, что образы Nginx и PHP принадлежат к одному поколению стека docker-magento.

---

Шаг 1: Обновите Docker-образ Nginx

Я обновил образ Nginx до современной версии:

app:
image: markoshust/magento-nginx:1.28-0

Раньше было:

app:
image: markoshust/magento-nginx:1.18-7

---

Шаг 2: Обновите конфигурацию Nginx для Magento

В новых образах Nginx используется переменная "$fastcgi_backend" для динамического выбора правильного сокета PHP-FPM.

Фактическая логика маршрутизации зашита прямо в кастомный образ Nginx, поставляемый с docker-magento.

Если вы посмотрите на исходный файл конфигурации Nginx в репозитории docker-magento на GitHub:

images/nginx/1.28/conf/default.conf (Строки 9-12)

https://github.com/markshust/docker-magento/blob/master/images/nginx/1.28/conf/default.conf#L9-L12

Вы можете увидеть, как именно это работает:

map $cookie_XDEBUG_SESSION $fastcgi_backend {
default fastcgi_phpfpm;
PHPSTORM fastcgi_phpfpm_xdebug;
}

Этот блок "map" читает куку "XDEBUG_SESSION".

Если кука существует, он устанавливает для "$fastcgi_backend" значение сокета Xdebug.

Если её нет, по умолчанию используется стандартный сокет PHP-FPM.

В моем старом образе Nginx этого блока map просто не было.

Чтобы это заработало в вашем локальном проекте, вам нужно обновить файл "nginx.conf" для Magento.

В моей конфигурации было:

fastcgi_pass fastcgi_backend;

а должно было стать:

fastcgi_pass $fastcgi_backend;

Этот небольшой знак "$" имеет решающее значение.

Без него Nginx воспринимает это значение как буквальное имя upstream-сервера, а не как переменную, и маршрутизация ломается.

Погодите, разве сетап Марка Шуста не делает это автоматически?

Да.

В новых версиях стека docker-magento появился вспомогательный скрипт под названием "bin/setup-nginx" (добавленный в коммите "80cc78d"):

https://github.com/markshust/docker-magento/commit/80cc78d1fef6cbcfda1d9226bd1fae041019501a

Этот скрипт автоматически переписывает строчку за вас.

Однако, поскольку я лишь обновил версии образов в своем файле "compose.yaml" и не запустил "bin/update" для получения последних вспомогательных скриптов, мой локальный каталог "bin/" устарел.

У меня в системе даже не было файла "bin/setup-nginx".

Именно поэтому мне пришлось добавлять знак "$" вручную.

---

Шаг 3: Пересоздайте Docker-контейнеры

После обновления образа и конфигурации:

docker compose down
bin/start

Окружение мгновенно поднялось, и ошибки 502 исчезли.

---

Итоги поиска и устранения неисправностей в Docker для Magento

Это была не проблема Magento.

Это была не проблема PHP.

И на самом деле даже не проблема Docker.

Это была проблема совместимости, вызванная смешиванием образов контейнеров из разных поколений стека docker-magento.

Урок для меня оказался двояким:

1. Docker-тома скрывают грехи.
Устаревший том может заставить неправильно настроенное окружение казаться абсолютно здоровым, пока вас не заставят его очистить.

2. Веб-серверы — это не просто «тупые трубы».
При обновлении версий PHP или любого компонента docker-magento убедитесь, что сопутствующие образы (например, Nginx) обновляются вместе с ними. В этом стеке они тесно связаны.

Один из способов избежать этого в будущем: жестко фиксировать (pin) версии образов PHP и Nginx в файле ".env", чтобы они всегда обновлялись парой, а не независимо друг от друга.

Кроме того, помните, что изменение версий образов в файле compose не приводит к автоматическому обновлению ваших локальных вспомогательных скриптов в "bin/"!

Надеюсь, это сбережет кому-нибудь несколько часов раздумий перед пропавшим "docker.sock" в попытках понять, куда он делся.

---

Ссылки

В процессе отладки этой проблемы мне помогли разобраться в изменениях между версиями образов следующие ресурсы:

- Репозиторий Docker Magento
https://github.com/markshust/docker-magento

- Файл compose.yaml для Docker Magento
https://github.com/markshust/docker-magento/blob/master/compose/compose.yaml

- История релизов Docker Magento
https://github.com/markshust/docker-magento/releases

Изменения, касающиеся обработки сокетов PHP-FPM и архитектуры выделенного контейнера Xdebug, становятся гораздо понятнее при сравнении старых и новых версий образов в описании релизов.