Docker로 개발환경 통일하기: 팀 협업의 게임체인저
🚨 "내 컴퓨터에서는 잘 되는데요?" - 개발팀의 영원한 고민
새로 입사한 주니어 개발자 김씨의 첫날이었습니다. 온보딩 문서를 따라 개발 환경을 세팅하는데 벌써 3시간째 삽질 중이었죠.
- Node.js 버전이 달라서 라이브러리가 설치되지 않음
- MySQL 버전 차이로 스키마 생성 실패
- Redis 연결 설정이 로컬과 달라서 에러 발생
- macOS vs Windows 환경 차이로 인한 파일 권한 문제
시니어 개발자들은 각자 다른 해결책을 제시했고, 결국 김씨의 첫 커밋까지는 일주일이 걸렸습니다. 이런 상황, 여러분 팀에서도 익숙하지 않으신가요?
🤔 우리 팀이 겪었던 개발환경 문제들
환경 불일치로 인한 시간 낭비
# 개발자 A (macOS, Node 18)
$ npm install
✅ 정상 설치
# 개발자 B (Windows, Node 16)
$ npm install
❌ node-gyp 빌드 에러
❌ 네이티브 모듈 컴파일 실패
# 개발자 A (macOS, Node 18)
$ npm install
✅ 정상 설치
# 개발자 B (Windows, Node 16)
$ npm install
❌ node-gyp 빌드 에러
❌ 네이티브 모듈 컴파일 실패
복잡한 온보딩 프로세스
기존 온보딩 문서는 20페이지가 넘었고, 각 OS별로 다른 설치 방법을 안내해야 했습니다:
# 기존 온보딩 문서 (일부)
## Windows 사용자
1. Node.js 16.14.2 설치 (정확한 버전 필수!)
2. Python 2.7 설치 (node-gyp 빌드용)
3. Visual Studio Build Tools 설치
4. MySQL 8.0 설치 및 설정
5. Redis 설치 및 실행
6. 환경변수 20개 설정
...
## macOS 사용자
1. Homebrew 설치
2. nvm으로 Node.js 16.14.2 설치
3. MySQL 8.0 설치 (brew 이용)
...
디버깅의 악몽
가장 고통스러운 순간은 운영 환경에서만 발생하는 버그를 디버깅할 때였습니다. 로컬에서는 재현되지 않는 문제들:
- 파일 경로 구분자 차이 (/ vs \)
- 환경변수 로딩 순서 차이
- 타임존 설정 차이
- 의존성 버전 미묘한 차이
💡 Docker 도입 결정: 게임체인저의 시작
프로젝트 데드라인이 촉박한 상황에서 새로운 팀원이 합류했는데, 개발환경 세팅만으로 2일을 날려버린 후 결정했습니다. "이제 정말 뭔가 바꿔야 한다!"
Docker 도입 목표
- 원클릭 개발환경 세팅: docker-compose up 한 번으로 모든 환경 구성
- 환경 일관성: 로컬, 개발, 스테이징, 운영 환경 100% 동일
- 온보딩 시간 단축: 1주일 → 30분으로 단축
- 의존성 지옥 탈출: 더 이상 "내 컴퓨터에서는 잘 돼요" 금지
🛠️ Docker 개발환경 구축 과정
1단계: 기본 Dockerfile 작성
# Dockerfile
FROM node:18-alpine
# 작업 디렉토리 설정
WORKDIR /app
# 시스템 의존성 설치 (네이티브 모듈용)
RUN apk add --no-cache python3 make g++
# package.json과 package-lock.json 복사 (캐싱 최적화)
COPY package*.json ./
# 의존성 설치
RUN npm ci --only=production
# 애플리케이션 코드 복사
COPY . .
# 애플리케이션 포트 노출
EXPOSE 3000
# 개발용 명령어
CMD ["npm", "run", "dev"]
2단계: docker-compose로 전체 스택 구성
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules # node_modules 오버라이드 방지
environment:
- NODE_ENV=development
- DB_HOST=mysql
- REDIS_HOST=redis
depends_on:
- mysql
- redis
command: npm run dev
mysql:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=myapp
- MYSQL_USER=appuser
- MYSQL_PASSWORD=apppassword
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./database/init.sql:/docker-entrypoint-initdb.d/init.sql
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- app
volumes:
mysql_data:
redis_data:
3단계: 개발 편의성을 위한 스크립트 작성
#!/bin/bash
# scripts/dev-setup.sh
echo "🚀 개발환경 초기화 중..."
# Docker와 Docker Compose 설치 확인
if ! command -v docker &> /dev/null; then
echo "❌ Docker가 설치되지 않았습니다."
exit 1
fi
if ! command -v docker-compose &> /dev/null; then
echo "❌ Docker Compose가 설치되지 않았습니다."
exit 1
fi
# 환경변수 파일 복사
if [ ! -f .env ]; then
cp .env.example .env
echo "✅ .env 파일이 생성되었습니다."
fi
# Docker 이미지 빌드 및 실행
echo "📦 Docker 이미지 빌드 중..."
docker-compose build
echo "🔄 서비스 시작 중..."
docker-compose up -d
# 데이터베이스 마이그레이션
echo "🗄️ 데이터베이스 마이그레이션 실행 중..."
docker-compose exec app npm run migrate
echo "🎉 개발환경 준비 완료!"
echo "👉 http://localhost:3000 에서 애플리케이션을 확인하세요."
4단계: 개발자 친화적인 설정
Hot Reload 지원
# Dockerfile.dev (개발용)
FROM node:18-alpine
WORKDIR /app
# nodemon 전역 설치
RUN npm install -g nodemon
COPY package*.json ./
RUN npm install # 개발용은 devDependencies도 설치
COPY . .
# 개발 서버 실행 (Hot Reload 지원)
CMD ["nodemon", "--watch", "src", "--ext", "js,json", "src/app.js"]
디버깅 지원
# docker-compose.override.yml (개발환경 오버라이드)
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
environment:
- NODE_ENV=development
- DEBUG=app:*
ports:
- "3000:3000"
- "9229:9229" # Node.js 디버거 포트
command: nodemon --inspect=0.0.0.0:9229 --watch src src/app.js
🚀 도입 후 드라마틱한 변화
온보딩 프로세스 혁신
Before (기존 방식)
소요 시간: 3-7일
1. OS별 개발도구 설치 (2-4시간)
2. 의존성 문제 해결 (4-8시간)
3. 데이터베이스 설정 (1-2시간)
4. 환경변수 설정 (1시간)
5. 실행 오류 디버깅 (2-16시간)
After (Docker 방식)
# 새로운 온보딩 프로세스
git clone https://github.com/company/project.git
cd project
chmod +x scripts/dev-setup.sh
./scripts/dev-setup.sh
# 끝! (총 소요시간: 5-15분)
실제 성과 지표
항목도입 전도입 후개선율
온보딩 시간 | 3-7일 | 30분 | 95% 단축 |
환경 관련 이슈 | 주 5-8건 | 주 0-1건 | 90% 감소 |
빌드 실패율 | 15% | 2% | 87% 개선 |
개발자 만족도 | 6.2/10 | 8.7/10 | 40% 향상 |
팀원들의 반응
김주니어: "첫날부터 코드에 집중할 수 있어서 너무 좋았어요. 환경 설정 때문에 스트레스받지 않으니까 개발이 재미있어졌어요!"
박시니어: "더 이상 '내 컴퓨터에서는 잘 돼요'라는 말을 안 듣게 되어서 행복합니다. 코드리뷰에서 진짜 중요한 것들에 집중할 수 있어요."
이팀장: "온보딩 시간이 단축되어서 새로운 팀원이 빨리 팀에 기여할 수 있게 되었습니다. ROI가 확실히 보이는 투자였어요."
🎯 Docker 도입시 주의사항과 팁
1. 성능 최적화는 필수
문제: 처음 Docker를 도입했을 때 개발 서버 시작이 너무 느렸습니다.
# ❌ 비효율적인 방법
COPY . .
RUN npm install
# ✅ 레이어 캐싱 활용
COPY package*.json ./
RUN npm install
COPY . .
추가 최적화 팁
# docker-compose.yml
services:
app:
volumes:
- .:/app
- /app/node_modules # node_modules 오버라이드 방지
- node_modules_cache:/app/node_modules # 캐시 볼륨 사용
2. 개발과 운영 환경 분리
# docker-compose.yml (기본)
version: '3.8'
services:
app:
build: .
# docker-compose.override.yml (개발용, 자동 로드됨)
version: '3.8'
services:
app:
volumes:
- .:/app
environment:
- NODE_ENV=development
# docker-compose.prod.yml (운영용)
version: '3.8'
services:
app:
environment:
- NODE_ENV=production
restart: unless-stopped
3. 보안 고려사항
# 보안을 위한 비루트 사용자 생성
FROM node:18-alpine
# 앱 사용자 생성
RUN addgroup -g 1001 -S appgroup && \
adduser -S appuser -u 1001 -G appgroup
# 작업 디렉토리 소유권 변경
WORKDIR /app
RUN chown appuser:appgroup /app
# 비루트 사용자로 전환
USER appuser
COPY --chown=appuser:appgroup package*.json ./
RUN npm ci --only=production
COPY --chown=appuser:appgroup . .
4. 로그 및 모니터링
# 로그 수집을 위한 설정
services:
app:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
🔄 CI/CD와의 연계
Docker를 도입한 후 CI/CD 파이프라인도 훨씬 간단해졌습니다:
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build and test
run: |
docker-compose -f docker-compose.test.yml build
docker-compose -f docker-compose.test.yml run --rm app npm test
- name: Build production image
if: github.ref == 'refs/heads/main'
run: |
docker build -t myapp:latest -f Dockerfile.prod .
docker push myapp:latest
📚 팀 내 Docker 문화 정착
1. 점진적 도입 전략
- 1주차: 메인 애플리케이션만 Docker화
- 2주차: 데이터베이스 추가
- 3주차: 캐시, 큐 등 부가 서비스 추가
- 4주차: 전체 스택 완성 및 안정화
2. 교육 및 문서화
# Docker 치트시트 (팀 내부 위키)
## 자주 사용하는 명령어
- 개발환경 시작: `docker-compose up -d`
- 로그 확인: `docker-compose logs -f app`
- 컨테이너 접속: `docker-compose exec app sh`
- 데이터베이스 초기화: `./scripts/dev-reset.sh`
## 문제 해결
- 포트 충돌: `docker-compose down && docker-compose up -d`
- 이미지 재빌드: `docker-compose build --no-cache`
- 볼륨 초기화: `docker-compose down -v`
3. 코드리뷰에 Docker 관련 체크리스트 추가
- Dockerfile 변경사항이 적절한가?
- docker-compose.yml 변경사항이 모든 환경에서 동작하는가?
- 새로운 의존성이 Dockerfile에 반영되었는가?
🎉 결론: Docker, 정말 게임체인저였다
Docker 도입 6개월 후, 우리 팀은 완전히 다른 팀이 되었습니다. 더 이상 환경 설정으로 시간을 낭비하지 않고, 진짜 중요한 비즈니스 로직 개발에 집중할 수 있게 되었어요.
예상치 못한 부수효과들
- 코드 품질 향상: 환경 일관성으로 인해 예측 가능한 코드 작성
- 팀 문화 개선: 기술적 스트레스 감소로 더 협력적인 분위기
- 신기술 도입 가속화: 새로운 서비스나 라이브러리 실험이 훨씬 쉬워짐
- 운영팀과의 협업 개선: 동일한 환경으로 인한 소통 효율성 증대
다음 단계: Kubernetes로의 여정
현재 우리 팀은 Kubernetes 도입을 검토하고 있습니다. Docker로 컨테이너화를 마스터한 지금, 오케스트레이션의 세계로 나아갈 준비가 되었거든요.
Docker 도입을 고민하고 계신 팀이라면, 지금이 바로 시작할 때입니다. 처음에는 러닝 커브가 있지만, 그 투자 대비 효과는 정말 크다고 자신있게 말씀드릴 수 있어요.
여러분의 Docker 도입 경험이나 궁금한 점이 있다면 댓글로 공유해주세요. 함께 더 나은 개발 문화를 만들어가요! 🚀
참고 자료