안녕하세요! 오늘은 Docker로 Redis 컨테이너를 실행하고, 로컬 터미널에서 redis-cli로 접속했는데 환경은 분리되어 있는데 컨테이너 속 데이터가 그대로 보이는 경우가있어서 궁금해서 찾아본 결과를 작성하였습니다.
사건의 발단
새로운 프로젝트를 위해 터미널에 익숙한 명령어를 입력합니다.
docker run --name my-redis -p 6379:6379 -d redis
my-redis라는 이름의 컨테이너가 백그라운드에서 잘 실행되고 있습니다. 이제 데이터가 잘 들어가는지 확인하기 위해, 새로운 터미널 창을 열고 redis-cli에 접속해봅니다.
# 새로운 터미널 창
redis-cli
127.0.0.1:6379> keys *
1) "RT:user123"
2) "post:likes:42"
... (애플리케이션이 저장한 키 목록)
그런데 이상합니다. 저는 분명 Docker 컨테이너 안에 Redis를 띄웠는데, 어떻게 로컬 PC에서 실행한 redis-cli가 컨테이너 속 데이터를 보고 있는 걸까요? 마치 내 컴퓨터에 직접 Redis를 설치한 것처럼 말이죠.
혹시 내가 모르는 사이에 로컬에도 Redis가 설치되어 있었나? 데이터가 복사라도 된 건가? 이런저런 생각에 잠시 혼란에 빠집니다.
범인은 바로 '포트 포워딩'
결론부터 말하면, 이것은 버그나 실수가 아닌 Docker의 매우 유용한 기능 덕분입니다. 범인은 바로 docker run 명령어에 사용했던 -p 6379:6379 옵션, 즉 **포트 포워딩(Port Forwarding)**입니다.
-p 옵션은 [호스트 포트]:[컨테이너 포트] 형식을 가집니다.
-p 6379:6379
"이 PC(호스트)의 6379번 포트로 들어오는 모든 네트워크 요청을, 저 Docker 컨테이너 내부의 6379번 포트로 전달(포워딩)해주세요."
마치 전화기의 '착신 전환' 기능과 같습니다. 내 자리(localhost:6379)로 걸려 온 전화를 지정된 다른 번호(Docker 컨테이너)로 자동으로 연결해주는 것이죠.
우리가 터미널에서 아무 옵션 없이 redis-cli를 실행하면, 이 프로그램은 기본적으로 localhost의 6379번 포트로 접속을 시도합니다. 이때 Docker가 이 요청을 가로채서 my-redis 컨테이너 안으로 투명하게 전달해주기 때문에, 우리는 마치 로컬에 직접 접속하는 것처럼 컨테이너 내부의 Redis와 통신할 수 있었던 것입니다.
직접 증명해보기: 컨테이너 속으로 직접 들어가보자
"정말 그런지 내 눈으로 확인해야겠어!" 라고 생각하신다면, docker exec 명령어로 컨테이너 안에서 직접 redis-cli를 실행해볼 수 있습니다.
# 실행 중인 'my-redis' 컨테이너 안에서 'redis-cli keys *' 명령어를 실행
docker exec my-redis redis-cli keys '*'
결과는 어떨까요? 놀랍게도(혹은 당연하게도) 로컬에서 실행했을 때와 완벽하게 똑같은 키 목록이 출력됩니다.
이것으로 데이터는 오직 Docker 컨테이너 안에만 존재하며, 로컬에서의 접속은 포트 포워딩이라는 가상의 통로를 통한 '원격 접속'이었음이 증명되었습니다.

마치며
이 간단한 원리 덕분에 개발자는 큰 축복을 받습니다. Spring Boot 애플리케이션의 application.yml 파일에 spring.redis.host=localhost 라고 설정하기만 하면 되고, IntelliJ 같은 IDE의 데이터베이스 툴에서도 localhost로 손쉽게 접속하여 데이터를 확인할 수 있습니다.
이제 Docker로 Redis를 띄우고 로컬에서 데이터가 보일 때 더 이상 당황하지 마세요. 그것은 여러분의 개발 경험을 한결 편하게 만들어주는 Docker의 똑똑한 마법이니까요



