도커 사용 시 노드.js 앱 성능 저하를 유발하는 10가지 실수
카테고리
프로그래밍/소프트웨어 개발
서브카테고리
DevOps
대상자
- Node.js 및 Docker를 사용하는 개발자, DevOps 엔지니어
- 중급 이상의 기술 수준을 요구하는 내용
핵심 요약
node:latest
대신node:18-alpine
같은 최소 기반 이미지 사용- 멀티스테이지 빌드로 빌드/런타임 의존성 분리
.dockerignore
파일을 통해 불필요 파일 제거 및npm ci --only=production
사용- 리소스 제한(
--memory
,--cpus
) 설정 및 비루트 사용자 권한 부여
섹션별 세부 요약
1. **잘못된 기반 이미지 사용**
node:latest
는 빌드 환경에 유리하지만, 생산 환경에서는 이미지 크기 증가 및 메모리 소비 증가node:18-alpine
사용 시 이미지 크기 약 5MB로 축소 가능- 보너스 팁: Alpine의 네이티브 모듈 문제 시
node:slim
사용
2. **멀티스테이지 빌드 미사용**
- 빌드 및 런타임 의존성 통합 시 이미지 크기 증가, 보안 위험 증가
- 멀티스테이지 빌드 예시:
FROM node:18-alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18-alpine
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]
3. **`.dockerignore` 파일 누락**
.env
,.git
,node_modules
등 불필요 파일 포함 시 빌드 속도 저하, 보안 취약점 발생.dockerignore
파일 생성 예시:
node_modules
npm-debug.log
Dockerfile
.dockerignore
.git
.env
tests
coverage
4. **루트 사용자로 실행**
- 보안 위험 증가: 루트 권한을 가진 공격자가 컨테이너에 접근 시 전체 시스템 제어 가능
- 비루트 사용자 생성 예시:
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
5. **건강 상태 검사(`HEALTHCHECK`) 누락**
- 기본적으로 Docker는 프로세스 실행 시 건강 상태로 간주
- Kubernetes 등 오케스트레이터와 호환 불가
HEALTHCHECK
예시:
HEALTHCHECK --interval=30s --timeout=10s --retries=3 CMD curl -f || exit 1
6. **구조화되지 않은 로깅 전략**
console.log()
사용 시 로그 파싱 어려움, 시간戳 및 심각도 누락- 구조화 로깅 라이브러리 사용 예시:
const pino = require('pino');
const logger = pino({ level: 'info' });
logger.info('Server started');
7. **리소스 제한 누락**
- OOM(Out Of Memory) 오류 발생 가능성
- Docker Compose 설정 예시:
services:
app:
image: my-node-app
deploy:
resources:
limits:
cpus: "0.50"
memory: "512M"
8. **도커파일 캐싱 비효율**
COPY . .
명령어를 의존성 설치 전에 배치 시 캐시 무효화- 효율적인 캐싱 순서 예시:
COPY package*.json ./
RUN npm ci
COPY . .
9. **개발 및 생산 환경 설정 혼합**
- 단일 Dockerfile 사용 시 생산 환경에 불필요한 도구 포함
- 분리된 Dockerfile(
Dockerfile.dev
,Dockerfile.prod
) 사용 권장
10. **이미지 리소스 관리 미비**
- 이미지 스캔 도구(
docker scan
,docker scout
) 사용 권장 - 이미지 정리 예시:
docker scout quickview my-node-app
docker scan my-node-app
결론
- 생산 환경에서는
node:18-alpine
기반 이미지 사용, 멀티스테이지 빌드 및.dockerignore
파일 생성 필수 - 리소스 제한(
--memory
,--cpus
) 설정과 비루트 사용자 권한 부여를 통해 보안 및 성능 강화 - 도커파일 캐싱 최적화 및 분리된 Dockerfile 사용으로 빌드 속도 향상 및 유지보수 용이성 증가