Ошибка Docker 'bind: address already in use': как найти процесс и освободить порт
Почему Docker не может запустить контейнер с пробросом порта
При попытке запустить контейнер командой docker run -p 80:80 ... или поднять проект через docker compose up процесс аварийно завершается с ошибкой: docker: Error response from daemon: driver failed programming external connectivity on endpoint ...: Bind for 0.0.0.0:80 failed: port is already allocated (или address already in use).
Причина сбоя
В сетевом стеке TCP/IP один сетевой порт в операционной системе может слушать только одна программа одновременно. Эта ошибка означает, что порт 80 (или 443, 3306, 8080) уже намертво занят другим запущенным процессом — локально установленным веб-сервером (Apache/Nginx) или другим забытым контейнером Docker.
Пошаговый алгоритм: поиск виновника и освобождение порта
Шаг 1: Поиск процесса, занявшего сетевой порт (ss / lsof)
Выполним поиск системного процесса, который слушает конфликтующий порт (например, порт 80):
sudo ss -tulpn | grep :80
или через утилиту lsof:
sudo lsof -i :80В последней колонке вы увидите точное имя программы (nginx, apache2, caddy) и ее цифровой идентификатор pid=1234.
Шаг 2: Вариант А — Порт занят системной службой (Apache / Nginx)
Если порт занят локально установленным сервером, который вам не нужен, остановите его и отключите автозагрузку:
sudo systemctl stop apache2
sudo systemctl disable apache2
или для Nginx:
sudo systemctl stop nginx
sudo systemctl disable nginxШаг 3: Вариант Б — Порт занят другим работающим контейнером Docker
Посмотрим список всех запущенных контейнеров с их опубликованными портами:
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}"Найдите контейнер, использующий этот порт, и остановите его:
docker stop имя_старого_контейнера
docker rm имя_старого_контейнераШаг 4: Вариант В — Смена внешнего порта для нового контейнера
Если вам нужно, чтобы на сервере одновременно работал и локальный сайт, и новый Docker-контейнер, просто пробросьте контейнер на другой свободный внешний порт (например, 8080):
docker run -d --name my-app -p 8080:80 nginx(Теперь сайт из контейнера будет открываться по адресу: http://IP_сервера:8080).
Шаг 5: Проверка успешного запуска контейнера
docker psТиповые ошибки администраторов
- Убийство Docker Proxy вместо целевого процесса: Процесс
docker-proxy— это системный шлюз самого Докера. Если убить его черезkill -9, сетевой стек демона Docker повредится. Контейнеры нужно останавливать исключительно штатной командойdocker stop. - Забытый Docker Desktop на Windows: Служба World Wide Web Publishing Service (IIS) в Windows по умолчанию занимает 80 порт при старте системы, блокируя запуск контейнеров веб-серверов.
Инженеры ITSTM развернут современный Reverse Proxy (Traefik / Nginx Proxy Manager), который автоматически распределит сотни контейнеров по доменным именам на едином 80/443 порту.
Частые вопросы (FAQ)
Что делать, если утилита lsof не установлена в системе?
Установите пакет lsof командой: sudo apt install lsof -y или воспользуйтесь стандартной утилитой ss: sudo ss -lptn 'sport = :80'.
Почему после docker stop порт все еще остается занятым пару секунд?
Операционная система удерживает сокет в состоянии TIME_WAIT для корректного закрытия TCP-пакетов. Подождите 10-15 секунд или перезапустите демон: sudo systemctl restart docker.
Как забиндить порт контейнера только на локальный адрес 127.0.0.1?
Укажите локальный IP перед портом хоста: docker run -p 127.0.0.1:8080:80 nginx. В этом случае порт не будет открыт в публичный интернет.
Что делать, если служба systemd-resolved заняла порт 53 DNS?
Для запуска своего DNS-сервера (Pi-hole/AdGuard) в Docker отключите DNSStubListener в файле /etc/systemd/resolved.conf (параметр 'DNSStubListener=no') и перезапустите службу.