NextJS 프로젝트를 Azure App Service Web app으로 배포해보자

eeeyooon·2024년 9월 15일
0


🌼 해당 글은 다음 스펙을 기준으로 작성되었습니다.

  • NextJS v14.1.0
  • pages router
  • typescript

NextJS 프로젝트를 Azure로 배포해보자

이미 이 배포 작업을 한 지 4개월 이상이 지났다. 그 당시 최대한 캡처하고, 기록은 했지만 빠진 정보가 있을 수도 있다. 가볍게 참고만 하면 좋을 것 같다.


1. 기본 디렉토리에 앱 등록

Azure 리소스 그룹 생성은 이미 마친 상태이다. (백엔드 개발자분들이 먼저 사용하셨고, 회사에서 초대해준 계정으로 이미 생성된 리소스 그룹에 웹앱을 추가할 예정이다.) 리소스 그룹 내에 기본 디렉토리에서 앱 등록 및 소유자 권한 등록을 해야 한다.


2. 웹 앱 생성 및 배포

웹앱 생성 이미지

해당하는 리소스 그룹을 선택하고 인스턴스 정보를 입력해야 한다.

  • 게시: 코드
  • 런타임 스택: Node 18 LTS
  • 운영 체제: Linux
  • 지역: Korea Central
  • 리눅스 플랜 B3

위 조건으로 웹 앱을 생성하였다.

배포 이미지

Azure Web Apps에서 리포지토리에 접근할 수 있도록 리파지토리 소유주 Github 계정을 연결해주었다. 그 뒤 해당하는 Organization, 리포지토리, 브랜치를 선택하면 된다.

최종적으로 내가 선택한 웹 앱 구성은 위와 같다. 마지막으로 확인해주고 "만들기" 버튼을 클릭하여 웹앱 생성을 완료한다.

웹 앱이 생성되면 자동으로 배포를 진행한다.

배포가 성공적으로 완료되었다. 해당 리포지토리의 액션을 확인해보면 build, deploy를 성공한 것을 볼 수 있다.

리포지토리 설정 > Secrets and variables에 Azure 관련 환경 변수가 자동으로 추가된 걸 볼 수 있다. 추가된다. 이 외에도 프로젝트에서 사용했던 .env 환경 변수를 추가한다.


3. 클라이언트 ID, 테넌트 ID, 구독 ID 가져오기

홈 > 기본 디렉토리 > 앱 등록 > 위에서 생성한 앱(나는 waved-client라는 이름이다.) 선택 > 개요

개요에서 애플리케이션(클라이언트) ID, 디렉터리(테넌트) ID 확인이 가능하다.

또한, 상단에서 "구독"을 검색하고 Microsoft Azure 스폰서쉽을 클릭하면 구독 ID 조회가 가능하다.


5. 깃허브 환경 변수에 필요한 ID 추가 및 YML 파일 수정

위에서 찾았던 ID값들을 각각 환경 변수에 추가해준다. 또한 자동으로 생성되어 있는 ".github > workflows > develop_waved-fe.yml" 파일에도 .env 및 ID 값들을 추가해준다. 참고 - yml 전체 코드

client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID }}
tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID }}
subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID }}

yml 파일명은 웹앱 생성 시 선택한 브랜치명 + 웹앱명으로 구성되는 것 같다.


6. 앱 등록을 했던 애플리케이션과 내가 만든 웹 앱 연결

1번에서 등록했던 애플리케이션과 2번에서 했던 웹 앱을 연결시키는 과정이다.

액세스 제어(IAM) > 역할 할당 추가 > 구성원 > 기여자 > 사용자, 그룹 또는 서비스 주체 (선택) > 앱 등록했던 애플리케이션 선택


7. 애플리케이션 자격 증명 설정

기본 디렉토리 > 앱 등록 > 해당 애플리케이션 선택 > 인증서 및 암호 > 페더레이션 자격 증명


8. 하지만,, 배포 실패 🥺

여기까지 마치고 build / deploy는 성공했으나, 에러가 발생하면서 배포 사이트가 제대로 열리지 않았다.

구글링하면서 계속 웹 앱 > 구성 > 일반 설정 > 시작 명령어를 수정하고 수정하고, worksflow에 있는 yml 파일에서 빌드 방식을 변경하고 변경했지만,, 여전히 제대로 배포되지 않았다.

공식 문서를 읽고, 더 구글링을 해본 결과 다음과 같은 원인 파악 및 결론을 낼 수 있었다.

  • node js로 구성된 서버는 npm, pm2, 사용자 지정 명령을 사용하여 시작하도록 앱을 구성할 수 있음.
  • Production 환경에서는 Azure app Service는 PM2를 사용하여 실행하도록 권장되고 있음. 참고
  • Node 14 LTS부터 컨테이너는 PM2로 앱을 자동 시작하지 않기 때문에 pm2를 사용하도록 하려면 루트 경로에 ecosystem.config.js 파일을 생성해서 azure app service를 시작하도록 해야함.

ecosystem.config.js 파일을 생성하고 start command를 추가해주었다.

pm2 --no-daemon start ecosystem.config.ts

ecosystem에 등록된 앱 모드를 실행하도록 명령한 것이다.


다시 실행해보니 ts-node가 필요하다는 로그가 떴다.

error: [PM2][ERROR] Interpreter /usr/local/lib/node_modules/pm2/node_modules/.bin/ts-node is NOT AVAILABLE in PATH. (type 'which /usr/local/lib/node_modules/pm2/node_modules/.bin/ts-node' to double check.)

ts-node를 설치해서 package.json에 반영된 것까지 확인한 뒤 develop에 Push하여 시도했으나, 또 같은 에러가 발생했다.


또 구글링 이후 pm2, typescript를 추가로 설치한 뒤 node_modules에 설치했다. 시작 명령어도 수정해봤지만 이번엔 BUILD_ID를 찾지 못한다는 에러가 발생했다. ㅋㅋㅋ.... 이 외에도 수정하면 할수록 다양한 에러를 만나게 됐다.


9. 문제 해결 및 배포 성공

하나를 해결하면 또 다른 에러가 발생하는 상황이 반복됐고 과정이 반복될수록 자꾸 근본적인 원인 해결과는 거리가 멀어지고 있다는게 느껴졌다. 제대로 원인이 파악되지 않은 상태에서 불필요한 수정을 반복하다보니 지금 무엇을 하고 있는지도 파악이 안되는 상황까지 왔다. 더이상 혼자 해봤자 시간만 걸릴뿐이라고 판단해서 다시 가장 처음의 상태 (7번까지 완료한 상태)로 돌리고 회사에서 멘토로 소개해준 분께 이메일을 남겼다.


현재 코드들과 내가 완료한 설정들, 어떤 문제가 발생했고 어떤 방법을 사용했는지 상황을 공유했고 답변으로 온 피드백대로 다시 작업을 시작했다. (사실 이메일은 미리 남겼지만 답변을 기다리는 동안 해볼 수 있는 건 다 해보려고 했다. 결국 실패했지만 🙃..)


workflows/develop_waved-fe.yml 파일을 다시 열어 build 관련 코드를 수정하였다.

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up Node.js version
        uses: actions/setup-node@v3
        with:
          node-version: '18.x'

      - name: npm install, build, and test
        run: |
          npm install
          npm run build --if-present
          npm run test --if-present

		// 이 부분이 수정한 부분이다.
      - name: Zip artifact for deployment
        run: zip release.zip ./* .next -qr

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v3
        with:
          name: node-app
          path: release.zip

수정된 부분은 다음과 같다.

[before]
run: zip release.zip ./* -r

[after]
run: zip release.zip ./* .next -qr

압축 목록에 .next를 추가하였고 옵션으로 -qr을 설정하였다. 이 옵션들에 대해 설명하면 다음과 같다.

-r: 이 옵션은 "recursive"의 약자로, 지정된 디렉토리를 재귀적으로 압축하라는 의미이다. 즉, 지정한 폴더 안의 모든 하위 폴더와 파일들을 포함시켜 압축 파일을 생성하라는 명령이다. 예를 들어 .next 디렉토리를 압축할 때 r 옵션을 사용하면 .next 내의 모든 하위 디렉토리와 파일들도 함께 압축된다.
-qr: 이 옵션은, qr 옵션이 결합된 것으로, q는 "quiet"의 약자로, 압축 과정에서 상세한 출력을 하지 않도록 하는 옵션이다. 즉, 압축 과정 중에 발생하는 일반적인 메세지나 경고가 표시되지 않는다. 따라서 qr을 사용하면, 디렉토리를 재귀적으로 압축하면서 동시에 압축 과정에서의 상세한 메세지 출력을 막는다.


다음으로, deploy 부분에 permissons를 추가하였다.

...

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'Production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
    permissions:
      id-token: write
...

이렇게 yml 코드 수정까지 완료하니 배포된 url로 사이트에 접속했을 때 화면이 아주 잘 나오고 있었다. 🥳🥳🥳 배포 성공했을 때의 기쁨을 떠올리니 다시 멘토님께 감사한 마음이 솟구친다. 정말 감사합니다. 감사합니다...🙏



최대한 기억을 살려서 작성 했지만 빠진 설정이나 yml 수정사항이 있을 수 있다. 특히 yml의 경우 전체 코드를 참고하는 것을 추천한다.

다음 포스팅으로는 Azure로 배포한 웹 사이트에 사용자 지점 도메인(가비아)을 연결하는 방법을 작성할 예정이다.



0개의 댓글