Как подружить 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