Ошибка Address already in use появляется в тот момент, когда программа пытается использовать порт, который уже занят другим процессом.
Обычно проблема возникает после запуска Nginx, Apache, Docker-контейнера, Gunicorn, Node.js, PostgreSQL или собственного приложения.
В этой статье разберем, как быстро определить, какой процесс занял порт, почему это произошло и как безопасно освободить его.
Любой сетевой сервис должен "занять" порт, чтобы принимать входящие подключения.
Например:
Если другой процесс уже слушает этот порт, операционная система запрещает запуск новой службы и возвращает сообщение:
bind(): Address already in use
или
OSError: [Errno 98] Address already in use
Система не позволяет двум процессам одновременно использовать один и тот же порт, иначе входящие соединения было бы невозможно правильно распределить.
Можно придерживаться последовательности:
Такой порядок помогает избежать ситуации, когда случайно останавливается рабочий сайт или база данных.
Например, вы запускаете Nginx, а Apache уже работает на порту 80.
Или пытаетесь запустить второй экземпляр Gunicorn на том же порту.
Посмотреть открытые порты можно командой:
ss -tlnp
Например:

LISTEN 0 511 0.0.0.0:80 users:(("nginx",pid=1352))
LISTEN 0 511 0.0.0.0:443 users:(("nginx",pid=1352))
LISTEN 0 244 127.0.0.1:5432 users:(("postgres",pid=841))
Если нужный порт уже присутствует в списке, причина найдена.
Команда ss практически всегда становится первым инструментом при диагностике подобных ошибок. Она быстрее большинства альтернатив и сразу показывает процесс, который занимает порт.
Иногда приложение аварийно завершается, но его процесс остается работать.
Например, после остановки сервера разработки Python или Node.js кажется, что программа закрылась, но один из процессов продолжает слушать порт.
Найти процесс можно так:
lsof -i :8000
Например:
COMMAND PID USER
python 2487 user
Если процесс больше не нужен, завершите его.
kill 2487
После этого повторите запуск приложения.

Если процесс не завершается обычной командой, стоит сначала выяснить причину. Использовать kill -9 имеет смысл только тогда, когда другие способы уже не помогли.
Иногда проблема возникает после ручного запуска приложения.
Например, Gunicorn уже работает как служба systemd, а затем его запускают еще раз вручную.
Или Node.js одновременно работает через PM2 и обычную команду:
node app.js
В результате оба процесса пытаются использовать один и тот же порт.
Проверьте список процессов.
ps aux | grep gunicorn
или
ps aux | grep node
Если обнаружились два одинаковых процесса, стоит разобраться, какой из них действительно должен работать постоянно.

При работе с Docker ошибка встречается часто.
Например:
docker run -p 80:80 nginx
Если порт 80 уже используется на хосте, контейнер не сможет запуститься.

Проверьте активные контейнеры.
docker ps
Обратите внимание на опубликованные порты.
Например:
0.0.0.0:80->80/tcp
Если этот порт уже используется контейнером, можно изменить публикацию.
Например:
docker run -p 8080:80 nginx
Так контейнер будет доступен на порту 8080, не мешая другим службам.
На новых VDS после установки панели управления или некоторых пакетов Apache может запускаться автоматически.
Затем пользователь устанавливает Nginx и получает ошибку:
bind() to 0.0.0.0:80 failed
Проверьте состояние служб.
sudo systemctl status nginx
sudo systemctl status apache2
или
sudo systemctl status httpd
Если Apache не используется, его можно остановить.
sudo systemctl stop apache2
После этого Nginx сможет занять порт.
Такую ситуацию особенно легко пропустить после установки готовых образов VPS, где часть служб уже настроена автоматически.
Через ss:
ss -tlnp | grep :8000
Через lsof:
lsof -i :8000
Через fuser:
fuser 8000/tcp
Все три команды показывают процесс, который использует нужный порт. Если какой-то утилиты нет в системе, обычно достаточно ss, так как она входит практически во все современные дистрибутивы Linux.
Если служба не запускается, стоит посмотреть ее журнал.
Например:
journalctl -u nginx -n 100
или
journalctl -u gunicorn -n 100
Также полезно проверить системный журнал.
journalctl -xe
Если нужно быстро найти причину ошибки, выполните несколько команд подряд.
ss -tlnp
lsof -i :8000
ps aux | grep gunicorn
systemctl status nginx
journalctl -xe
Для других служб достаточно заменить номер порта и название процесса.
Этот набор позволяет определить, кто использует порт, проверить состояние службы и посмотреть последние сообщения системы.
Ошибка Address already in use означает, что выбранный порт уже используется другим процессом. Чаще всего причиной становится уже запущенная служба, оставшийся после сбоя процесс, конфликт настроек или публикация порта в Docker.