보이스피싱 탐지용 KoBERT 및 딥페이크 음성 판별 모델을 Flask API 서버로 구현한 후,
Docker를 활용해 Google Cloud Platform(GCP) VM 인스턴스에 배포하는 과정에서 다양한 문제에 직면하게 되었습니다.
그중 대표적인 세 가지 문제와 실제로 적용한 해결 방법을 정리하였습니다.
문제 1 GCP 웹 SSH 접속 무한 대기 현상
증상
GCP 콘솔에서 인스턴스에 접속하기 위해 "SSH로 접속" 버튼을 클릭하였으나,
"SSH 서버와의 연결 설정 중..."이라는 메시지만 표시되고 실제 연결은 이루어지지 않았습니다.
원인
- GCP가 웹 브라우저를 통해 SSH 키를 자동 등록하는 과정에서 실패했을 가능성
- 또는 VM 내부의 sshd 서비스가 제대로 기동되지 않았을 가능성
해결 방법
- VM 설정에서 "직렬 포트를 통해 연결 허용" 항목을 활성화한 후,
시리얼 포트 로그를 통해 SSH 데몬 기동 상태를 확인하였습니다. - 터미널에서 수동 접속을 시도하기 위해 아래 명령어를 사용할 수 도 있습니다.
- 저는 그냥 인스턴스를 중지하고 다시 재실행 하니깐 됐습니다!
gcloud compute ssh <INSTANCE_NAME> --zone=<ZONE>

아니면 위 로그를 찍어 볼 수도 있습니다!
문제 2 Flask 서버 접속 실패 (WinError 10061)
증상
로컬 개발 환경에서 python test_0.py 명령어를 통해 GCP 서버에 요청을 보냈을 때,
다음과 같은 오류 메시지가 발생하였습니다.
HTTPConnectionPool(host='127.0.0.1', port=5000): Max retries exceeded...
[WinError 10061] 대상 컴퓨터에서 연결을 거부했으므로 연결하지 못했습니다
원인
- test_0.py 내부에서 127.0.0.1:5000으로 요청을 보내고 있었으나,
이는 로컬 PC의 IP 주소를 의미하며 실제 Flask 서버는 GCP VM 내부에서 구동되고 있었습니다. - Docker 컨테이너가 실행 중이지 않거나, 외부에서 접속 가능한 포트로 바인딩되어 있지 않았을 가능성도 있습니다.
- 127.0.0.1:5000은 예시 IP 입니다!
사용한 명령어 흐름 (순차적 요약)
# 컨테이너 상태 확인
docker ps -a
# 컨테이너 로그 확인
docker logs -n 100 voicephishing-container
# 기존 컨테이너 및 이미지 제거
docker stop voicephishing-container
docker rm voicephishing-container
docker rmi voicephishing-app
# Docker 이미지 재빌드
docker build -t voicephishing-app .
# 컨테이너 재실행 (포트 5000 개방)
docker run -d -p 5000:5000 --name voicephishing-container voicephishing-app
해결 방법
- 상태 -> 로그 순서로 확인 후 이미지를 제거 하고 다시 재실행 하니깐 실행 됐습니다.
- GCP 콘솔에서 외부 IP를 확인하고, 방화벽 설정을 통해 TCP 5000 포트가 개방되어 있는지 점검하였습니다.
문제 3 Docker 컨테이너가 자동 종료됨 (Exited (255))
증상
Docker로 Flask 서버를 실행한 직후에는 잘 동작하는 듯 보였으나,
몇 초 후 docker ps -a 명령어를 확인했을 때 컨테이너가 Exited (255) 상태로 종료된 것을 확인하였습니다.
원인
Flask 서버가 다음과 같은 설정으로 실행되고 있었습니다.
app.run(host="0.0.0.0", port=5000, debug=True)
- 이 경우 debug=True 설정으로 인해 Flask 내부적으로 use_reloader=True가 자동 활성화되며,
코드 변경 감지를 위해 자식 프로세스를 생성하고 부모 프로세스를 종료하게 됩니다. - Docker에서는 PID 1이 종료되면 전체 컨테이너가 종료되므로, Flask 재시작 로직 자체가 문제의 원인이 됩니다.
해결 방법
server.py 파일의 __main__ 블록을 다음과 같이 수정하였습니다.
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=False, use_reloader=False)
이후 Docker 이미지를 재빌드하고, 컨테이너를 다시 실행하여 안정적으로 서버가 유지되도록 하였습니다.
결론
GCP 환경에서 Flask + Docker 조합으로 API 서버를 운영하는 과정에서
기본적인 개발 서버 설정만으로는 실제 운영에서 요구되는 안정성과 신뢰성을 확보하기 어렵다는 점을 체감하였습니다.
이러한 문제를 해결해 나가며 다음과 같은 중요한 교훈을 얻었습니다.
- Flask는 개발 서버용이며, 운영 환경에서는 반드시 gunicorn과 같은 WSGI 서버를 도입하는 것이 바람직합니다.
- Docker 컨테이너 내부에서는 PID 1 프로세스의 종료가 곧 컨테이너의 종료이므로, Flask의 리로딩 옵션을 반드시 비활성화해야 합니다.
- GCP에서는 외부 IP, 포트 개방 여부, 방화벽 설정, 시리얼 로그 분석 등 다양한 환경 요소에 대한 이해가 필요합니다.
이후에는 gunicorn 기반의 다중 워커 구성, Nginx 리버스 프록시 및 HTTPS 인증서 적용 등을 통해
보다 신뢰성 있는 API 서버 구조로 고도화해 나갈 예정입니다.
'Backend & Infra > Docker' 카테고리의 다른 글
| 로컬에서 프로젝트(PDFMASK) 서비스를 Docker로 실행하는 방법 (0) | 2025.11.26 |
|---|---|
| Docker 명령어 정리 (자주 사용하던 명령어_2) (1) | 2025.06.04 |
| GCP 서버에 (Flask + Gunicorn) + KoBERT + Whisper 기반 음성피싱 탐지 시스템 구축기 (1) | 2025.05.27 |
| GCP에서 Docker를 활용한 딥러닝 모델 API 서버 배포 실습 (0) | 2025.05.20 |
| Docker를 사용할 때 가장 자주 쓰는 명령어 정리 (0) | 2025.05.20 |