"Step #2 - "Deploy": ERROR: (gcloud.run.services.update) Revision is not ready and cannot serve traffic. The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable. Logs for this revision might contain more information."
timestamp: "2024-05-09T06:55:48.683036613Z"
에러 등장 ..
이전에 더미 파일로 빌드를 진행했을때 완벽하게 잘 되었기 때문에 바로 작업파일로 진행을 했었는데
빌드가 실패했다.
이유가 뭔지 에러 문구를 읽었는데 단순히 포트가 중복되어서 에러가 난게 아닐까 라고 생각하게 되었다.
그래서 포트를 변경해주고 진행을 했는데 같은 오류가 등장하는 것이었다.
그래서 정확한 로그를 보기위해서 로그파일로 접근해서 확인해봤다.
Error: Cannot find module '/workspace/index.js'
at Module._resolveFilename (node:internal/modules/cjs/loader:1145:15)
at Module._load (node:internal/modules/cjs/loader:986:27)
at Function.executeUserEntryPoint as runMain
at node:internal/main/run_main_module:28:49 {"
Cannot find module '/workspace/index.js ??
찾아보니 해결방법으로 npm install 을 하라고 한다.
정상적으로 배포된 (더미) 와 비교해봤을때 bulid 과정이 없었다.
npm run bulid 명령어를 사용해서 빌드를 진행하는데 내가 작업한 코드에서는 빌드 과정이 아예 생략되었었다.
그래서 /workspace/index.js 에러가 발생한것이었다.
왜일까 생각해보니
순수 nextjs 에서는 bulid 명령어가 package.json에는 잘 적혀있다.
하지만 나는 env-cmd를 사용하기 때문에 bulid와 start에 변형을 주었었다.
내 package.json script
내 코드에서 bulid는 순수 bulid명령어가 아니고 bulid:dev 이다..
아마 yaml파일에서 자체적으로 bulid명령어를 찾지 못해서 스킵한것 같다.
google run에서는 기본으로 yaml파일을 말아주는데 gcr.io/k8s-skaffold/pack, gcr.io/buildpacks/builder 등 구축된 로직을 따라서 빌드 로직이 실행되기 때문에 이 패키지들을 까봐야했다.
자체적으로 패키지 명령어가 npm bulid로 정해진듯 하다.
steps:
- name: gcr.io/k8s-skaffold/pack
args:
- build
- >-
$_AR_HOSTNAME/$PROJECT_ID/cloud-run-source-deploy/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA
- '--builder=gcr.io/buildpacks/builder:v1'
- '--network=cloudbuild'
- '--path=.'
id: Buildpack
entrypoint: pack
- name: gcr.io/cloud-builders/docker
args:
- push
- >-
$_AR_HOSTNAME/$PROJECT_ID/cloud-run-source-deploy/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA
id: Push
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk:slim'
args:
- run
- services
- update
- $_SERVICE_NAME
- '--platform=managed'
- >-
--image=$_AR_HOSTNAME/$PROJECT_ID/cloud-run-source-deploy/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA
- >-
--labels=managed-by=gcp-cloud-build-deploy-cloud-run,commit-sha=$COMMIT_SHA,gcb-build-id=$BUILD_ID,gcb-trigger-id=$_TRIGGER_ID
- '--region=$_DEPLOY_REGION'
- '--quiet'
id: Deploy
entrypoint: gcloud
images:
임시적으로 가설을 세웠으니 검증을 해보게 되었다.
가설 : bulid 명령어가 고정되어 있는데 나는 bulid명령어가 custom이기 때문에 bulid 명령어를 찾지 못하는게 아닐까?
그래서 내 package.json명령어를 bulid로 수정해주었다.
테스트 해본결과 가설이 맞았다.
bulid로 명령어를 수정해준 결과 빌드가 성공했고 웹사이트가 정상적으로 보였다.
임시방편으로 문제를 해결하긴 하였지만 main을 배포할때마다, dev를 배포할때마다 script를 계속 변경해줘야 한다는게 불편하기도 하고 제대로된 방법이 아닌것 같았다.
yaml 파일을 수정해서 배포해보도록 수정했다.
- name: node
args:
- install
entrypoint: npm
- name: node
env:
- 'NEXT_PUBLIC=${_NEXT_PUBLIC}'
args:
- run
- 'build:dev'
entrypoint: npm
이렇게 수정하니 명령어가 먹혔다. run bulid:dev 명령어가 먹히긴 했는데 기존것은 gcr.io에서 있는 패키지들을 사용해서 도커로 연결하기 때문에 어떻게 조합을 해도 빌드가 되지 않았다.
기존 생성된 yaml 파일에서는 경로를 $_AR_HOSTNAME/$PROJECT_ID/cloud-run-source-deploy/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA 으로 지정해서 도커와 연결해서 사용해야 하는데
내가 수정한 yaml 파일 코드에서는 $_AR_HOSTNAME/$PROJECT_ID/cloud-run-source-deploy/$REPO_NAME/$_SERVICE_NAME:$COMMIT_SHA 경로로 빌드를 하지 않아서 도커에서 경로 에러가 계속 나타났다.
결국 패키지 내부의 명령어 (npm run bulid)를 수정해야 하는데 패키지 내부를 수정하기가 어려워서 검색좀 하다가 포기하게 되었다.
대부분 검색을 하면 해외 블로거 사람들이 Docker로 빌드하는 방법에 대해서 많이 올라와 있었다.
나는 도커를 쓰는것이 환경도 설정해야 하고 어려울것 같아서 기본으로 사용하려고 했었는데 에러가 계속 해소가 되지 않아서 도커를 사용하기로 결정하게 되었다.
도움은 이 사이트에서 도움을 받았다
next14 google cloude run 빌드 방법 영문판
도커 코드를 복사해서 챗GPT에게 모르는 부분을 계속 물어봐서 코드를 대충 파악할수 있었다.
나는 dev와 prod로 나눠야 했기 때문에 도커도 .dev와.prod로 나눠주었다.
경로 수정과 명령어를 수정하고 내 도커 코드를 만들수 있었다.
FROM node:18-alpine AS base
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package*.json ./
RUN npm ci
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED 1
RUN npm run build:dev
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["npm", "run", "start:dev"]
도커에서 빌드할때는 RUN명령어를 사용하고 실행할때는 CMD명령어를 사용한다고 한다.
따로 환경을 설정한것이 아니고 그냥 Dockerfile만 새로 생성하고 새로운 프로젝트를 google cloude에서 만들어 주었다.
( docker로 빌드하도록 설정해야 하기 때문에 )
내가 참고했던 사이트에서 상세히 나와 있다.
주의 할점이라면 프로젝트를 만들면 포트를 3000포트로 변경해주어야 한다.
빌드를 시작하니 .env 환경에 관해 명령어는 잘먹혔다. 하지만 빌드 실패 ..?!!
start 부분에서 계속 에러가 났다.
Error: Failed to find .env file at path: ./.env.development
at getEnvFile
.env.development 에서 .env파일을 찾을수 없다 ?
뭐가 문제인지 도커 파일에 .env파일이 없는건지 ? 도커 파일 내부에서 디렉토리를 전부 검색해봤다.
RUN ls -al << 이게 도커에서 전체 디렉토리를 찍는것이다.
확인해보니 .env.development 파일이 있었다.
왜 에러가 나는 지 몰라서 검색해보니 다른 언어들의 해결방법들만 나와 있어서 계속 로직을 수정해가며 배포 테스트를 진행했다.
내 스크립트는 아래와 같다 .
bulid까지는 env파일로 제대로 빌드를 시작하는데 start에서는 왜 찾을수 없는지 모르겠다.
계속되는 실패에 생각을 해보니 bulid할때 .env.development의 환경변수들로 빌드를 하는데 시작을 할때도 굳이 .env.development로 실행을 해야 하나 ? 생각을 해서 start명령을 그냥 next start로 변경해줬다.
결과는 성공이었다.
진짜 몇시간 동안 실패하다가 성공하는 초록 체크를 보니 엄청 반가웠다. (감격의 눈물흘릴뻔..ㅜㅜ)
콘솔로 환경변수들을 체크해보니 잘 찍혔다.
dev도 성공했으니 prod버전으로 나눠서 배포를 진행해봐야 겠다..
2일 정도 걸려서 고군분투했던 빌드 성공으로 마무리