CI CD 완성을 위한 학습 기록 - boostcampwm-2022/web33-Mildo GitHub Wiki

🐬 고려 사항

  • 지난번에 main branch에 .env파일 잘못 올려서 문제 생겼으니 조심스럽게 병합하기
  • main branch에 pull request 이후 merge되면 actions 실행 시키기
  • 계획한 actions 실행 흐름
    • github runner 환경으로 checkout
    • runner 환경에서 v16.10.0 노드 설치
    • client 디렉토리에서 yarn 의존성 패키지 설치
    • client 디렉토리에서 yarn build로 빌드 파일 생성
      • /client/build
    • server 디렉토리에서 yarn 의존성 패키지 설치
    • server .env 파일 생성
    • server 디렉토리에서 yarn build로 빌드 파일 생성
      • /server/dist/src
    • runner 환경에서 appleboy로 배포 서버에 ssh 원격 접속
      • appleboy/scp-action
        • runner 서버의 source를 배포 서버의 target으로 copy
      • appleboy/ssh-action
        • runner 서버에서 배포 서버로 원격 접속 후 script 실행
    • 배포 서버에서 client build 파일 nginx 실행 경로로 옮기고 시작하기
    • 배포 서버에서 pm2로 server 시작하기
  • nginx로 배포할 때는 특정 디렉토리에 빌드 파일을 넣어줘야 하고, pm2로 배포할 때는 그냥 pm2 start 해당 경로를 입력하며 됨

🩺 의사결정

  • dev에서 main으로 병합할 때 PR만 사용하기
  • runner 환경에서 .env 생성해서 배포 서버의 server 디렉토리로 복사하기
  • 서버 build 명령어는 npx tsc -p .인데 이게 ts를 js로만 바꿔주고 .env까지 번들링한 파일을 생성하는 것은 아닌 것으로 보임
    • 서버 빌드 경로 : server/dist/src
    • tsc는 typescript를 javascript로 번들링해줄뿐 이외의 모듈들은 번들링되지 않는 것 같음
    • 이전 기수에서는 웹팩을 이용해 ts → js 뿐만 아니라 .env파일, node-module 모두 한번에 번들링 해주는 것 같음
  • 클라이언트 빌드 명령어는 yarn build로 실제 react-script가 동작함
    • 클라이언트 빌드 경로 : client/build

🚧 트러블 슈팅 및 알게 된 사실

client 폴더를 찾을 수 없는 오류

  • main 브랜치에는 아직 client, server 코드 모두 없었기 때문에 client 폴더를 찾을 수 없다는 오류 발생
  • dev 브랜치를 main 브랜치로 merge하여 해결

appleboy/scp-action의 source

source: './client/build/*'
target: '/usr/share/nginx/html'
  • 다음과 같이 github action yml 파일에 작성했지만 예상한 동작은 ./client/build 폴더에 들어있는 모든 파일을 /usr/share/nginx/html 폴더로 복사되는 것으로 생각함
  • 하지만 실제 배포 서버에서는 /usr/share/nginx/html/client/build/ 에 파일들이 복사되어 있었다.
  • 해결하지 못하고 nginx의 정적파일 폴더 경로를 /usr/share/nginx/html/client/build/ 로 바꾸어 해결
  • .env 파일이 server/dist 에 넣어지지 않고 상위 폴더까지 통째로 복사됨 → runner 서버에서 .env 파일을 root에서 생성하고 복사하여 해결, 하지만 pm2 에러가 해결되지 않음

runner 서버에서 client 빌드 오류

Untitled

  • 프로젝트마다 설치된 라이브러리들이 경고를 다르게 감지하여 생기는 오류
  • 해결법 : env에서 CI 속성을 false 로 설정

‘node’ : No such file or directory 에러

Run appleboy/ssh-action@master
/usr/bin/docker run --name b0df17ad6642cab9df787b94909821_b00163 --label 290506 --workdir /github/workspace --rm -e "client-directory" -e "server-directory" -e "CI" -e "INPUT_HOST" -e "INPUT_USERNAME" -e "INPUT_PASSWORD" -e "INPUT_PORT" -e "INPUT_SCRIPT" -e "INPUT_PASSPHRASE" -e "INPUT_SYNC" -e "INPUT_USE_INSECURE_CIPHER" -e "INPUT_CIPHER" -e "INPUT_TIMEOUT" -e "INPUT_COMMAND_TIMEOUT" -e "INPUT_KEY" -e "INPUT_KEY_PATH" -e "INPUT_FINGERPRINT" -e "INPUT_PROXY_HOST" -e "INPUT_PROXY_PORT" -e "INPUT_PROXY_USERNAME" -e "INPUT_PROXY_PASSWORD" -e "INPUT_PROXY_PASSPHRASE" -e "INPUT_PROXY_TIMEOUT" -e "INPUT_PROXY_KEY" -e "INPUT_PROXY_KEY_PATH" -e "INPUT_PROXY_FINGERPRINT" -e "INPUT_PROXY_CIPHER" -e "INPUT_PROXY_USE_INSECURE_CIPHER" -e "INPUT_SCRIPT_STOP" -e "INPUT_ENVS" -e "INPUT_DEBUG" -e "HOME" -e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_ACTOR" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "GITHUB_STATE" -e "GITHUB_OUTPUT" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e GITHUB_ACTIONS=true -v "/var/run/docker.sock":"/var/run/docker.sock" -v "/home/runner/work/_temp/_github_home":"/github/home" -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" -v "/home/runner/work/_temp/_runner_file_commands":"/github/file_commands" -v "/home/runner/work/web33-Mildo/web33-Mildo":"/github/workspace" 290506:66b0df17ad6642cab9df787b94909821
======CMD======
nvm use default
cd web33-Mildo/server/dist/src
pm2 start app.js
pm2 reload app.js

======END======
err: bash: nvm: command not found
err: /usr/bin/env: ‘node’: No such file or directory
out: 
2022/11/24 07:04:02 Process exited with status 127
out: 
err: /usr/bin/env: ‘node’: No such file or directory
  • 원인 : pm2를 실행하기 위해서는 node 환경이 필요한데, 배포 서버에서 node가 전역적으로 설치되지 않았었음
  • 해결 : node를 root 디렉토리에서 사용할 수 있게 전역적으로 설치하고 nvm을 사용해서 버전을 16.10.0으로 조정하였음
    • 기타
    • 실제 클라우드 서버에 접속했을 때는 nvm 명령어를 사용할 수 있었지만, github Actions를 이용하여 nvm 스크립트를 적용했을 때 다음과 같은 오류 발생
      • err: bash: nvm: command not found
    • ubuntu에서 nvm 설치 방법

pm2 배포 지속적인 에러

/root/.pm2/logs/app-error.log last 15 lines:
0|app      | Require stack:
0|app      | - /root/web33-Mildo/server/dist/src/app.js
0|app      |     at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
0|app      |     at Module.Hook._require.Module.require (/usr/local/share/.config/yarn/global/node_modules/pm2/node_modules/require-in-the-middle/index.js:81:25)
0|app      |     at require (node:internal/modules/cjs/helpers:102:18)
0|app      |     at Object.<anonymous> (/root/web33-Mildo/server/src/app.ts:1:1)
0|app      |     at Module._compile (node:internal/modules/cjs/loader:1101:14)
0|app      |     at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
0|app      |     at Module.load (node:internal/modules/cjs/loader:981:32)
0|app      |     at Function.Module._load (node:internal/modules/cjs/loader:822:12)
0|app      |     at Object.<anonymous> (/usr/local/share/.config/yarn/global/node_modules/pm2/lib/ProcessContainerFork.js:33:23)
0|app      |     at Module._compile (node:internal/modules/cjs/loader:1101:14) {
0|app      |   code: 'MODULE_NOT_FOUND',
0|app      |   requireStack: [ '/root/web33-Mildo/server/dist/src/app.js' ]
0|app      | }
  • 문제점 : pm2에서 배포 시 위와 같은 오류가 지속적으로 발생함
  • 원인 : 네이버 클라우드 서버에서 3001번 포트를 열어주지 않아서 발생한 오류로 보임
  • 해결
    • 네이버 클라우드 서버에서 3001번 포트를 열어줌
    • server 디렉토리 전체를 배포 서버로 옮김

변경된 파일이 실행되지 않는 에러

  • server/dist/src/app.js (번들된 파일)에는 새롭게 추가된 코드들이 작성되어있는데, 실행시키면 해당 코드가 적용되지 않고 이전 코드들이 실행됨
  • pm2를 restart하여 해결

서버 에러

  • 서버 포트를 3001으로 변경했는데, 네이버 클라우드 서버의 ACG 설정에서 포트번호 3001번을 열어주지 않아서 오류 발생
  • 설정 변경으로 오류 해결

네이버 지도 API 에러

  • 클라이언트에서 네이버지도를 불러오지 못함
  • 네이버 지도 API에 배포용 주소를 추가하여 해결

CORS 에러

  • cors 오류 → 환경변수 CLIENT_URL에 [http://를](http://를) 붙여주지 않음
    • ip주소도 프로토콜을 정확하게 명시해줘야 함

MongoDB 환경변수 설정 에러

- name: 서버 env 파일 설정
    run: | 
      touch .env
      echo SEOUL_CITY_API_ACCESS_KEY=${{ secrets.SEOUL_CITY_API_ACCESS_KEY }}\ >> .env
      echo SEOUL_CITY_API_ACCESS_KEY_SUB=${{ secrets.SEOUL_CITY_API_ACCESS_KEY_SUB }}\ >> .env
      echo MONGODB_CONNECT_URI=${{ secrets.MONGODB_CONNECT_URI }}\ >> .env
      echo NAVER_CLIENT_ID=${{ secrets.NAVER_CLIENT_ID }}\ >> .env
      echo NAVER_CLIENT_PASSWORD=${{ secrets.NAVER_CLIENT_PASSWORD }}\ >> .env
      echo CLIENT_URL=${{ secrets.CLIENT_URL }}\ >> .env
      echo API_SERVER_PORT=${{ secrets.API_SERVER_PORT }}\ >> .env
  • MONGODB_CONNECT_URI 를 설정해주었고, Actions를 실행시키면 출력되는 것까지 확인했지만, 배포 환경에서 이 변수만 자동으로 적용되지 않는 에러 발생

🐕 개선점

  • MongoDB 환경변수 설정은 아직 원인을 해결하지 못하고 배포 환경에서 일일이 환경변수를 입력해줌
    • echo MONGODB_CONNECT_URI=${{ secrets.MONGODB_CONNECT_URI }}\ >> ~/web33-Mildo/server/dist/.env 로 해결해볼 수 있지 않을까?란 희망을 가져봄
  • 지금은 server 디렉토리 전체를 배포 환경으로 옮기고 있는데 dist만 옮기면 될 것 같음
  • cache 적용으로 node.js와 client 의존성 패키지 설치 시간 줄이기 (직접 측정해보면 좋을 듯)
  • 개발용/배포용 환경변수 분리
    • URL을 수동으로 바꿔줘야 해서 너무 불편함
  • (선택) 웹팩을 적용해보자

👁️‍🗨️ 참고 자료

⚠️ **GitHub.com Fallback** ⚠️