Nginx Proxy Manager Docker에서 'No file descriptors available' 에러 해결하기
NPM Plus(Nginx Proxy Manager) 컨테이너가 갑자기 접속 불가 — accept4() failed (24: No file descriptors available) 에러의 원인과 해결법을 정리합니다.
Nginx Proxy Manager Docker에서 'No file descriptors available' 에러 해결하기
증상
NPM Plus(Nginx Proxy Manager) Docker 컨테이너가 갑자기 모든 요청을 거부하면서 로그에 아래 에러가 초당 2회씩 쏟아졌다.
[crit] 733314#733314: accept4() failed (24: No file descriptors available)
관리자 페이지(/api/)에 접근하면 upstream 연결도 실패한다.
[alert] *338373 socket() failed (24: No file descriptors available)
while connecting to upstream, client: 127.0.0.1, server: _,
request: "GET /api/ HTTP/2.0", upstream: "http://127.0.0.1:48681/"
원인
File Descriptor(fd) 한도 초과다.
Linux에서 네트워크 소켓, 로그 파일, upstream 연결 등은 모두 fd를 하나씩 소비한다. Docker 컨테이너의 기본 fd 한도는 1024개인데, nginx처럼 동시 연결이 많은 프로세스는 이 한도를 쉽게 넘긴다.
fd가 바닥나면 nginx는 새로운 TCP 연결을 accept()할 수 없게 되고, 결과적으로 모든 요청이 차단된다.
fd 고갈이 발생하는 일반적 원인
- upstream 응답 지연: 백엔드가 느려지면 nginx가 연결을 오래 물고 있음
- keepalive 과다: 클라이언트가 연결을 닫지 않고 유지
- 로그 파일 누적: 로그 로테이션 미설정 시 fd 점유
- 프록시 호스트 과다: 관리하는 도메인/서비스가 많을수록 기본 fd 소비 증가
즉시 해결: 컨테이너 재시작
docker restart npmplus
재시작하면 모든 fd가 해제되면서 즉시 복구된다. 하지만 근본 원인을 해결하지 않으면 재발한다.
재발 방지: ulimits 설정
docker-compose.yml에 ulimits를 추가해서 fd 한도를 높인다.
services:
npmplus:
image: zoeyvid/npmplus:latest
# ... 기존 설정
ulimits:
nofile:
soft: 65536
hard: 65536
soft와 hard의 차이
| soft | hard | |
|---|---|---|
| 의미 | 현재 적용되는 실제 한도 | 올릴 수 있는 최대 천장 |
| 변경 권한 | 프로세스가 hard 이하까지 자유롭게 변경 | root만 변경 가능 |
쉽게 말하면 soft는 "지금 쓰는 한도", hard는 "최대 여기까지 올릴 수 있다"는 상한선이다. 보통 둘 다 같은 값으로 설정하면 된다.
설정 후 적용:
docker compose up -d npmplus
적용 확인
컨테이너에 접속해서 한도를 확인한다.
docker exec npmplus sh -c "ulimit -n"
65536이 출력되면 정상 적용된 것이다.
더 상세하게 보려면:
# nginx 프로세스의 실제 fd 사용량
docker exec npmplus sh -c "ls /proc/$(pgrep nginx | head -1)/fd | wc -l"
# 프로세스별 한도 확인
docker exec npmplus sh -c "cat /proc/$(pgrep nginx | head -1)/limits | grep 'Max open files'"
정리
| 단계 | 명령 | 목적 |
|---|---|---|
| 1. 즉시 복구 | docker restart npmplus |
fd 해제로 서비스 복구 |
| 2. 재발 방지 | ulimits.nofile: 65536 설정 |
fd 한도 64배 증가 |
| 3. 적용 확인 | docker exec npmplus ulimit -n |
설정값 검증 |
Docker 컨테이너의 기본 fd 한도(1024)는 nginx 같은 리버스 프록시에 턱없이 부족하다. ulimits 한 줄이면 해결되는 문제니, NPM/NPM Plus를 Docker로 운영한다면 처음부터 설정해두는 것을 권장한다.
Member discussion