port 옵션 없이 도커를 올렸다면, 내부에서만 curl이 되고 외부에서는 curl을 해 보았자 찾을 수 없다고 뜰 겁니다.
저는 fastapi 서버를 8080번 포트로 실행하였습니다. 그리고 host인 제 로컬 머신에서 localhost:8080으로 접근하려고 시도했습니다. 하지만, 컨테이너 위의 8080번 포트에서 돌고 있는 것이지, host에서 돌고 있는 것이 아닙니다.
즉, docker run publish port 옵션을 사용하지 하지 않았기 때문에, host의 8080번에서 접근을 시도해도 되지 않습니다. host에서 돌고 있는 것도 아니고요. 그런데, curl localhost:8080/health 명령어를 컨테이너 내부에서 수행하면 이야기가 달라집니다.
이는, 컨테이너 내부에서 8080번 포트로 fastapi 서버가 돌아가고 있기 때문입니다. 그리고, 저는 /health router를 간단하게 만들어 두었기 때문에 응답이 성공합니다. 만약에, host에서 8080번 포트로 docker container 내에 있는 fastapi 서버에 접근하려면 어떻게 해야 할까요? 이 때 쓸 수 있는 것이 -p, publish 옵션입니다.
docker run publish port 옵션 사용해 보기
먼저, fastapi 프로젝트를 봅시다.
vscode에서 Dockerfile 익스텐션을 설치하셨다면 쉽게 빌드할 수 있습니다. Dockerfile을 우클릭 하고 Build Image를 누릅니다. 그러면 이런 창이 뜰 겁니다. 여기서, Enter를 눌러서 build를 하겠습니다. 여담으로, –port 8080 옵션은 8080번 포트로 서버를 실행시킨다는 의미입니다.
-p 옵션을 사용하였는데요. 여기서 중요한 것은 8080:8080입니다. {host}:{container}인데요. 컨테이너의 8080번 포트가 host의 8080번 포트에 맵핑되게 됩니다. 아래 그림과 같은 상황이 되는 셈입니다.
이제, host에서 localhost:8080으로 접속해 보겠습니다. fastapi의 경우 /docs로 접속하면 swagger-ui가 나옵니다. 그리고, /redoc으로 접속하면 문서 ui가 나옵니다.
docs로 접속하니까 swagger가 매우 잘 나왔음을 볼 수 있습니다. 정리하면 host의 8080번 포트를 통해서, docker container 내부의 8080번 포트로 접근이 가능했던 셈입니다.
netstat -ntlp 명령어를 치면, 네트워크 연결 정보를 조회할 수 있어요. :::8080이 있고요. 상태가 LISTEN입니다. 8080번 포트를 누군가 쓰고 있다는 의미입니다. 이제 Dockerfile을 조금 바꿔서 실행해 볼게요.
Dockerfile 바꿔서 실행해 보기
해당 파일의 8번째 줄만 바꿔서 실행해 보겠습니다.
8번째 줄의 CMD만 조금 바뀌었는데요. –port가 8000번입니다. 이는, 컨테이너 내부에서 fastapi 서버가 8080번이 아니라 8000번 포트로 실행된다는 의미입니다. 이 경우, container의 8000번 포트를 host의 8080번 포트로 mapping을 시켜줘야 합니다. 따라서 -p 8080:8000 옵션을 적어줘야 합니다.
위 명령어는 아래 그림과 같은 일을 수행합니다.
host의 8080번 포트를 통해서, 컨테이너 내부의 8000번 포트로 접근이 가능하게 된 셈입니다. 즉, host의 port를 통해서 container의 port로 접근하게 하기 위해 publish 옵션을 쓰는 것이라고 생각하면 되겠습니다.