며칠 전, GitHub Actions에서 도커 빌드가 계속 실패하는 문제를 만났다.
“뭐야, 어제까지 잘되던 게 왜 갑자기 안 돼?”
로그를 보니 다음과 같은 익숙한 문장이 떠 있었다.
Error: buildx failed with: ERROR: failed to solve: process "/bin/sh -c npm install" did not complete successfully: exit code: 127
“아, 또 npm install 문제야?”
이미 수십 번은 봤던 에러라 대충 해결법도 알고 있었다.
“캐시 문제인가?” “base image가 바뀐 건가?”
이런저런 가설을 세워보며 평소처럼 Dockerfile을 뜯어봤다.
그런데 뭔가 이상했다.
어제는 분명 잘되던 코드인데, 내가 수정한 부분은 ENV NODE_ENV=production을 추가한 것뿐이었다.
“설마 이거 때문인가?”
📌 ENV NODE_ENV=production 한 줄이 가져온 혼돈
보통 NODE_ENV=production은 배포 환경을 위해 설정하는 필수적인 변수다.
덕분에 불필요한 개발용 패키지(devDependencies)를 설치하지 않게 최적화할 수 있다.
그러니까, 이걸 추가하는 게 당연히 좋다고 생각했는데… 빌드가 망가졌다.
혹시나 싶어 ENV NODE_ENV=production을 삭제하고 다시 실행했다.
그리고 기적처럼 빌드가 정상적으로 진행됐다.
“뭐야, 대체 왜 안 되는 거야?”
한참 삽질한 끝에 문제를 깨달았다.
“아, NODE_ENV=production을 npm install 전에 설정하면 devDependencies가 설치되지 않잖아?”
📌 npm install이 실패한 이유
우리는 NestJS를 사용하고 있었다.
NestJS 프로젝트에서는 빌드할 때 typescript, @nestjs/cli 같은 패키지가 필요하다.
그런데 이런 패키지들은 package.json의 devDependencies에 들어 있다.
그러니까, NODE_ENV=production을 미리 설정해버리면 npm install이 devDependencies를 무시해버리는 것!
그리고 npm run build를 실행할 때 필요한 TypeScript 관련 패키지가 없어서 빌드가 실패하는 거였다.
결국, 문제는 ENV NODE_ENV=production을 배치한 위치였다.
📌 올바른 NODE_ENV=production 설정 방법
이 문제를 해결하기 위해 NODE_ENV=production을 실행 환경에서만 설정하는 방식으로 변경했다.
🚀 잘못된 Dockerfile (빌드 실패)
FROM node:20
WORKDIR /usr/src/app
ENV NODE_ENV=production # ❌ 여기에 설정하면 devDependencies가 설치되지 않음
COPY package*.json ./
RUN npm install # ❌ 빌드에 필요한 패키지가 빠져서 실행 중 오류 발생
COPY . .
RUN npm run build # ❌ TypeScript 관련 패키지 없음 → 빌드 실패
📌 이렇게 설정하면 NestJS 프로젝트에서 TypeScript 관련 패키지가 없어서 빌드가 실패할 가능성이 크다.
✅ 수정된 Dockerfile (정상 동작)
# 1️⃣ 빌드 컨테이너 (devDependencies 포함)
FROM node:20 AS builder
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install # ✅ devDependencies 포함하여 설치
COPY . .
RUN npm run build # ✅ TypeScript 등 빌드 패키지가 정상적으로 설치됨
# 2️⃣ 실행 컨테이너 (불필요한 패키지 제거)
FROM node:20
WORKDIR /usr/src/app
COPY --from=builder /usr/src/app/dist ./dist
COPY --from=builder /usr/src/app/node_modules ./node_modules
COPY --from=builder /usr/src/app/package.json ./package.json
# ✅ 실행 환경에서만 NODE_ENV=production 설정
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "dist/main.js"]
✅ 이렇게 하면:
• 빌드 컨테이너에서는 devDependencies를 포함한 상태로 설치 → 빌드 성공
• 실행 컨테이너에서는 NODE_ENV=production을 설정 → 프로덕션 최적화
📌 결론: NODE_ENV=production의 위치가 중요하다
이 삽질을 통해 얻은 교훈은 간단하다.
🚨 ”ENV NODE_ENV=production을 npm install 전에 설정하면 빌드가 망가질 수 있다.”
🔹 NODE_ENV=production은 실행 환경에서만 설정하는 게 맞다.
🔹 빌드 단계에서는 devDependencies가 필요할 수도 있기 때문에, 멀티 스테이지 빌드를 활용하자.
🔹 GitHub Actions에서 buildx 오류가 난다면, 가장 먼저 ENV NODE_ENV=production 위치를 의심하자!
한 줄의 설정으로 인해 몇 시간을 삽질할 수도 있다.
🚀 배포 최적화를 위한 핵심 정리
✅ NODE_ENV=production을 npm install 전에 설정하면 devDependencies가 설치되지 않는다.
✅ npm install → npm run build 이후에 ENV NODE_ENV=production을 설정하는 것이 가장 안전하다.
📢 마무리하며
이 글을 보고 있는 당신이 나처럼 한 줄 때문에 몇 시간을 날리는 삽질을 피할 수 있길 바란다.
그리고 앞으로 Dockerfile을 작성할 때, “이 환경 변수 하나가 어떤 영향을 미칠까?” 라는 질문을 던지는 습관을 가져야겠다.
'Study' 카테고리의 다른 글
k진수에서 소수개수 구하기 (0) | 2022.09.24 |
---|---|
[python] csv, error (0) | 2022.08.06 |
[python] Class (0) | 2022.08.05 |
시간 복잡도 (0) | 2022.06.21 |
boj 1406 javascript (0) | 2022.06.20 |