Docker: bind address already in use — конфликт портов 80 и 443
Ошибка при запуске docker-compose up
При поднятии нового контейнера с веб-сервером или базой данных в терминале появляется красная ошибка:
Error response from daemon: driver failed programming external connectivity on endpoint ...: Bind for 0.0.0.0:80 failed: port is already allocated.Причина сбоя
Docker не может занять сетевой порт хоста, потому что он уже открыт локальной службой (например, предустановленным Apache) или другим контейнером.
Пошаговое устранение конфликта портов
- Определяем, какой процесс занял порт 80 или 443:
# Утилита ss (рекомендуется): sudo ss -tulpn | grep -E ":(80|443)" # Либо через классический netstat: sudo netstat -tulnp | grep :80 - Вариант 1: Если порт занял локальный Apache/Nginx:
sudo systemctl stop apache2 && sudo systemctl disable apache2 - Вариант 2: Если порт занят другим забытым Docker-контейнером:
docker ps | grep :80 docker stop ID_КОНТЕЙНЕРА - Вариант 3: Если порт нужен другой программе — меняем внешний порт в docker-compose.yml:
# Меняем левую цифру (порт на хосте): ports: - "8080:80" # Внешний порт 8080 ведет на 80 порт контейнера - Перезапускаем проект:
docker compose up -d
В связке портов 8080:80: левое число — это порт на физическом сервере, правое — внутренний неизменяемый порт внутри контейнера.
Частые вопросы (FAQ)
Почему после docker stop контейнер снова занимает порт после перезагрузки?
У контейнера стоит restart: always. Удалите его (docker rm) или измените политику перезапуска.
Что делать, если порт занят процессом docker-proxy?
Это внутренний демон Docker. Остановите конфликтующий контейнер через docker stop.
Как быстро завершить процесс, зная только номер порта?
Выполните команду: sudo fuser -k 80/tcp.
Как привязать порт только к локальному интерфейсу 127.0.0.1?
В docker-compose укажите: '127.0.0.1:8080:80'.