쓸툴.site
Tech & Story

Docker와 CI/CD: '내 컴퓨터에선 되는데'를 방지하는 배포 전략

📅 2025-12-14 👨‍💻 에디터 K
Docker와 CI/CD: '내 컴퓨터에선 되는데'를 방지하는 배포 전략

모든 개발자의 악몽, "내 컴퓨터(Local)에서는 잘 되는데 서버(Production)에만 올리면 에러가나요"입니다. 저 역시 이번 프로젝트를 배포하면서 OS 차이, 파이썬 버전 차이, 설치된 라이브러리 버전 차이로 인해 숱한 500 에러를 겪었습니다.

이 문제를 근본적으로 해결하기 위해 Docker(도커)를 도입했습니다. 애플리케이션 실행에 필요한 모든 환경을 컨테이너라는 상자에 담아 배포함으로써, 로컬과 서버의 환경을 100% 동일하게 맞출 수 있었습니다.

1. 가벼운 컨테이너를 위한 Dockerfile 최적화

처음 작성한 Docker 이미지는 용량이 1GB가 넘었습니다. 불필요한 패키지까지 다 포함되었기 때문입니다. 이를 줄이기 위해 python:3.9-slim 같은 경량화된 베이스 이미지를 사용하고, .dockerignore 파일을 설정하여 __pycache__.git 같은 불필요한 파일이 빌드 컨텍스트에 포함되지 않도록 했습니다.

또한, pip install 과정에서 캐시를 남기지 않도록 --no-cache-dir 옵션을 사용하여 이미지 크기를 300MB 수준으로 다이어트시켰습니다. 가벼운 이미지는 더 빠른 배포와 스케일링을 가능하게 합니다.

2. 쉘 스크립트(Shell Script)로 배포 자동화하기

매번 서버에 접속해 git pull, docker build, docker run을 치는 건 비효율적이고 실수하기 딱 좋습니다. 저는 deploy.sh라는 배포 스크립트를 작성해 이 과정을 자동화했습니다.

이 스크립트는 기존 컨테이너를 안전하게 종료하고, 최신 코드를 받아 빌드한 뒤, 새로운 컨테이너를 실행하는 모든 과정을 명령어 하나로 처리합니다. 특히 docker system prune 명령어를 포함시켜 배포할 때마다 쌓이는 쓰레기 이미지(Dangling Images)를 자동으로 정리하도록 하여 서버 디스크 용량 관리까지 해결했습니다.

3. 502 Bad Gateway와의 사투

Nginx와 Flask 컨테이너를 연동하는 과정에서 502 에러가 빈번했습니다. 원인은 주로 컨테이너가 완전히 뜨기 전에 Nginx가 요청을 보냈기 때문이거나, 소켓 파일의 권한 문제였습니다.

이를 해결하기 위해 docker-composedepends_on 옵션을 활용하고, Gunicorn의 로그 레벨을 debug로 낮춰 구체적인 에러 원인을 추적했습니다. 결국 문제는 환경 변수 설정 미스였습니다. 로그(Log)는 거짓말을 하지 않는다는 진리를 다시금 되새긴 경험이었습니다.

🐳 컨테이너의 바다로

Docker를 도입한 이후, 저는 더 이상 "서버 환경 설정" 때문에 스트레스를 받지 않습니다. 코딩에만 집중할 수 있는 환경, 이것이 바로 DevOps가 주는 최고의 선물입니다.

개발자로서의 삶을 체험해보고 싶다면?

👨‍💻 개발자 키우기 게임 플레이

이 글이 도움이 되셨나요?

친구들에게 공유하고 함께 이야기해보세요!

🤖