Загрузка...

Docker Desktop vs нативный Docker на Linux: Хроники неочевидных конфликтов

Как не сойти с ума, установив Docker Desktop поверх Docker Engine на Linux: лайфхак выжившего разработчика
docker

Как подружить Docker Desktop и нативный Docker в Linux: пошаговое руководство по устранению конфликтов

Введение

Типичная история: разработчик на Ubuntu или Kubuntu решает поставить Docker Desktop ради красивого UI и удобного управления контейнерами. До этого всё прекрасно работало — старый добрый Docker Engine, docker-compose, сборки летали.

После установки Docker Desktop начинается череда странных ошибок, на первый взгляд никак не связанных между собой. Сначала ломается composer, потом Redis жалуется на “address already in use”, а напоследок появляется “mounts denied”. Что случилось и как всё вернуть в рабочее состояние — разбираемся пошагово.


Проблема №1: Ошибка сети при сборке (composer:latest)

Первая тревожная строчка в консоли:

failed to resolve source metadata for docker.io/library/composer:latest: failed to do request: Head "https://registry-1.docker.io/v2/library/composer/manifests/latest": EOF

Причина оказалась нетривиальной. Docker Desktop на Linux работает внутри виртуальной машины со своим собственным сетевым стеком. Когда в Dockerfile используется команда вроде COPY --from=composer:latest, контейнер пытается стянуть образ напрямую из Docker Hub — но изнутри изолированной среды Desktop это может закончиться таймаутом или EOF.

Решение:

Использовать прямую установку Composer через curl вместо промежуточного COPY:

RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

Этот способ надёжнее, потому что полностью контролируется внутри текущего контейнера и не зависит от внешних multi-stage слоёв.


Проблема №2: Конфликт портов (address already in use)

После успешной сборки контейнеров раздаётся новый звоночек:

listen tcp 0.0.0.0:6379: bind: address already in use

Redis отказывается стартовать. На первый взгляд кажется, что какой-то другой сервис занял порт. Но на деле всё сложнее: старый нативный Docker Engine всё ещё работает где-то в фоне. Его контейнеры продолжают использовать те же порты, но Docker Desktop о них ничего не знает.

Настоящая причина: конфликт контекстов Docker

Docker в Linux теперь живёт в двух мирах:

  • default — старый контекст с нативным движком.
  • desktop-linux — контекст, используемый Docker Desktop.

Чтобы разобраться, достаточно выполнить:

docker context ls

Переключиться на старый контекст:

docker context use default
docker ps

Вы увидите все “потерянные” контейнеры, которые по-прежнему работают. Завершите их корректно:

docker compose down

Вернуться обратно в Docker Desktop:

docker context use desktop-linux

Можно было бы просто поменять порт в docker-compose.yml, но это не лечит сам конфликт. Контейнеры так и остались висеть в фоне. Лучше один раз навести порядок — потом будет спокойнее.


Проблема №3: Ошибка монтирования (mounts denied)

Когда сборка и запуск прошли, но до рабочего окружения остаётся один шаг — приложение падает с ошибкой:

mounts denied: The path /tmp/ssh-XXXXXX/agent is not shared from the host.

Docker Desktop VM видит только ограниченный набор директорий на хосте — обычно /home/user. Всё, что вне этой зоны (например, временные файлы в /tmp), недоступно. В случае с SSH-агентом это оборачивается запретом монтирования сокета.

Быстрое решение:

В docker-compose.yml просто закомментируйте строки, связанные с переменной SSH_AUTH_SOCK:

# environment:
#   SSH_AUTH_SOCK: /tmp/ssh-agent.sock

Контейнер сразу запустится.

Если SSH-агент действительно нужен (например, для приватных репозиториев), добавьте путь к /tmp в список доступных директорий:
Settings → Resources → File Sharing в интерфейсе Docker Desktop.


Заключение

Docker Desktop на Linux — мощный инструмент, но он изменяет архитектуру окружения:

  • Установкой появляется новый контекст desktop-linux, отдельный от старого Docker Engine.
  • Старые контейнеры остаются активными в контексте default, занимая порты.
  • Доступ к файловой системе теперь ограничен — не все пути видны внутри Desktop VM.

Зато после устранения всех конфликтов система работает стабильно: красивый UI, удобное управление контекстами и логами, автообновления — всё это можно теперь использовать без потери контроля над своими контейнерами.

 

Чеклист перед установкой Docker Desktop на Linux

  • Проверь запущенные контейнеры в нативном Docker Engine:
docker context use default
docker ps
  • Останови и удали проекты, которые используют сети и порты:
docker compose down
  • Выясни, какие контексты Docker уже есть и куда переключиться:
docker context ls
  • Перед запуском Docker Desktop переключись на контекст desktop-linux:
docker context use desktop-linux
  • Проверь, не используешь ли монтирование временных файлов из /tmp в docker-compose.
    • При необходимости измени путь или добавь /tmp в секцию File Sharing Docker Desktop.
  • При необходимости Composer — не используй copy из официального образа, а устанавливай напрямую через curl:
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
  • Если нужен SSH-агент в контейнере — заранее добавь /tmp в File Sharing или настрой agent forwarding через рабочие каталоги.
  • Сохрани список стандартных портов и проверь, не заняты ли они:
sudo lsof -i -P -n | grep LISTEN

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *