안녕하세요. 도커 입문 중인데 하루 종일 붙잡고 있어서 도움 요청드립니다.
docker-compose up 하면 Redis 컨테이너는 정상적으로 뜨는데, 앱 컨테이너에서 Redis에 붙으려고만 하면 계속 연결 거부가 납니다.
Error: connect ECONNREFUSED 127.0.0.1:6379
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:...)docker-compose.yml 입니다.
services:
app:
build: .
ports:
- "3000:3000"
redis:
image: redis:7
ports:
- "6379:6379"앱 코드에선 이렇게 연결합니다.
const client = createClient({ url: 'redis://127.0.0.1:6379' });
await client.connect();로컬에서 node로 직접 돌릴 땐 잘 됐는데 컨테이너 안에서만 안 됩니다. 포트도 6379로 열어놨는데 왜 거부될까요?
댓글 2
안녕하세요. 아주 흔하게 겪는 부분입니다. 원인은
127.0.0.1이 컨테이너 기준의 localhost라는 데 있습니다.컨테이너 안에서
127.0.0.1은 그 앱 컨테이너 자기 자신을 가리킵니다. 호스트 PC나 Redis 컨테이너가 아니에요. 그래서 앱 컨테이너 내부의 6379 포트로 붙으려다 아무도 안 듣고 있으니ECONNREFUSED가 납니다. 로컬에서 직접node로 돌릴 땐 앱과 Redis가 같은 머신(호스트)의 localhost를 공유했으니 됐던 거고요.docker-compose는 서비스마다 내부 DNS 이름을 만들어 줍니다. 서비스 이름을 호스트로 쓰면 됩니다. 여기선
redis죠.하드코딩보다는 환경변수로 빼는 걸 권장합니다.
두 가지만 더 짚어드리면:
ports:로 6379를 호스트에 노출할 필요도 없습니다(호스트에서 직접 접속할 게 아니라면 지워도 됩니다).depends_on은 Redis 컨테이너가 시작되기만 기다릴 뿐 준비 완료까지 보장하진 않습니다. 앱이 먼저 붙으려다 실패할 수 있으니, 클라이언트에 재연결 로직을 두거나 healthcheck를 걸어두는 게 안전합니다.