ListenStream= и другие Listen…= в сокет-unit
Задаёт адрес, который systemd будет слушать для сокета потокового типа: номер порта, адрес с портом или путь к unix-сокету. Для других типов есть ListenDatagram=, ListenFIFO= и родственные параметры.
Что делает
Смысл сокет-активации в том, что порт открывает systemd, а не служба. Это даёт две вещи: службу можно запускать по первому обращению, и при перезапуске службы соединения не теряются — их держит systemd.
Формат значения зависит от вида адреса: одно число — порт на всех интерфейсах, адрес:порт — конкретный интерфейс, путь начиная с косой черты — unix-сокет.
Где ставится. В секции [Socket]. Можно указать несколько строк — сокет будет слушать все адреса.
Значения
| Значение | Что происходит |
|---|---|
8080 | TCP-порт на всех интерфейсах. |
127.0.0.1:8080 | только петлевой интерфейс. |
[::1]:8080 | адрес IPv6 в квадратных скобках. |
/run/myapp/app.sock | unix-сокет; каталог создаётся через RuntimeDirectory=. |
Пример
Сокет с unix-адресом и правами для веб-сервера.
[Socket]
ListenStream=/run/myapp/app.sock
SocketUser=app
SocketGroup=www-data
SocketMode=0660
[Install]
WantedBy=sockets.target
Права на сокет задаются здесь, а не в службе: файл создаёт systemd, и он же выставляет владельца.
Типичные ошибки
Сокет без единого Listen…= не загружается: systemd сообщает, что unit не настроен.
Порт, уже занятый самой службой, приводит к конфликту: выбирайте один способ — сокет-активацию или самостоятельную привязку.
Для unix-сокета нужен существующий каталог: используйте RuntimeDirectory=.
В автозапуск нужно ставить сокет, а не службу.
Связанные ошибки
- Сокет без Listen: unit загружен, но ничего не слушаетВ .socket не задан ни один параметр Listen…= — сокет не принимает соединения. Как объявить адрес прослушивания.
- Address already in use при запуске службыПорт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- Служба не получает сокет при сокет-активацииСокет активен, служба запускается, но не находит переданный дескриптор. Разбор: Accept, FileDescriptorName, соответствие имён.
- Сокет и служба включены одновременно: конфликт при загрузкеПри сокет-активации в автозапуск включена и служба, и сокет. Порт занимает то, что стартовало первым.
Рядом стоящие параметры
Где важен на практике
Источники
- systemd.socket(5)
- Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)