Heroku로 Express 서버 배포하기
Heroku로 Express 서버 배포하기

Heroku로 Express 서버 배포하기

작성자
이태용이태용
카테고리
deploy
태그
frontend
backend
deploy

배포 과정

폴더 경로 구조는 이렇다.
app |---backend |---frontend
나는 Gibhub Pages(프론트) + heroku(백엔드)로 연동하여 배포하고자 했다.
우선 heroku cli를 설치했다.
$ npm install -g heroku (cli 설치 명령어)
다음은 heroku에 로그인 해야한다.
$ heroku login
아무키나 누르면 새창이 나타나면서 로그인 하라고 한다.
계정은 미리 회원가입을 한 상태여서 바로 로그인했다.
notion image
로그인 성공
notion image
 
그 다음 heroku에 프로젝트 이름을 만들었다.
$ heroku create ${PROJECT-NAME}
 
이제 git init으로 remote에 heroku를 추가했다.
git remote -v로 잘 연결되었는지 확인도 해주었다.
notion image
이제 커밋 & 푸쉬해보자.
$ git add . $ git commit -m "${commit message} $ git push heroku master
빌드업 진행 중 아래 코드가 나타나면서 빌드 실패가 됐다.
! No default language could be detected for this app. HINT: This occurs when Heroku cannot detect the buildpack to use for this application automatically. See <https://devcenter.heroku.com/articles/buildpacks> ! Push failed
빌드팩을 설치하라고 한다.
공식 문서에 나온 대로 아래 코드로 nodejs 빌드팩을 설치했다.
공식문서 https://devcenter.heroku.com/articles/buildpacks
heroku buildpacks:set heroku/nodejs
다시 한번 git push heroku master했더니 다른 오류가 나왔다.
Heroku was unable to automatically detect the type of app you're trying to deploy
찾아본 결과 루트 디렉토리에 Procfile 생성하라고 한다. Procfile은 heroku에게 프로젝트를 실행하기 위한 명령어의 순서를 알려주는 용도이다. 앱을 업로드한 후 Heroku가 노드 js 웹 서버를 시작하는 방법과 같은 dynos 설정을 정의할 Heroku 파일이다.
web : node ${package에 있는 실행 명령어 or 루트디렉토리 index파일 = server.js 입력 }
나는 CRA가 아닌 node로 사용했기 때문에 루트 디렉토리 <code>node ${index파일명.js}</code>으로 입력하였다. 그런데도 똑같은 에러가 났다. 구글링으로 web : node 에서 띄어쓰기 버그를 발견했다.
하지만 실패.
노드와 npm 버전이 다를 수도 있다는 의견이 나왔다. 그래서 직접적으로 버전을 설정해주었다.
"engines": { "node": "16.15.0", "npm": "8.5.5" },
그래도 실패.
이쯤되면 구조나, 빌드방식이 잘못되었다는 판단이 들었다. 그러던 중 root 디렉토리에 package.json이 없어서 그런 것이었다는 걸 찾게 되었다.
server 폴더안에 frontend 부분을 포함시켜 다른 레포지토리로 분리 할 수 있었으나, 루트 디렉토리 안에 각각의 파일경로로 관리하고 싶었기 때문에 git subtree를 사용하면 분리하지 않을 수 있었다.
https://stackoverflow.com/questions/5977234/how-can-i-push-a-part-of-my-git-repo-to-heroku
git subtree push --prefix web heroku master
드디어 서버 빌드에 성공하게 되었다.
경로: https://${FROJECT_NAME}.herokuapp.com/$ {api경로}
notion image
 
깃허브를 선택하고 Deploy Branch 눌렀더니 아래와 같은 에러가 나왔다.
ERROR: Application not supported by 'heroku/nodejs' buildpack ! ! The 'heroku/nodejs' buildpack is set on this application, but was ! unable to detect a Node.js codebase. ! ! A Node.js app on Heroku requires a 'package.json' at the root of ! the directory structure. ! ! If you are trying to deploy a Node.js application, ensure that this ! file is present at the top level directory. This directory has the ! following files: ! ! app/ ! README.md ! ! If you are trying to deploy an application written in another ! language, you need to change the list of buildpacks set on your ! Heroku app using the 'heroku buildpacks' command.
추측되는 경우는 2가지다. 하나는 해당 디렉토리에 package.json 누락되어서다. 하지만 이건 subtree로 우회해결하였다. 다른 하나는 heroku가 빌드팩을 감지 못하고 있는 것이다. 여기까지 삽질까지도 꽤나 긴 시간이 걸렸다. 그래서 결국 포기하고 app > backend > frontend 경로로 변경했다.
app |---backend |---frontend
이 방식은 실제로 헤로쿠에 배포할 때는 익스프레스 서버에 리액트 빌드 파일을 배포하여 사용할 것이다. 그래서 위에 삽질했던 방식과는 달리 backend의 package.json이 heroku 호출에 반응할 것이다. 이 경우 빌드를 하기 위해서는 별도 셋팅이 필요하다.
 

서버 동시 시작

클라이언트단과 서버단 통신 연결은 이미 한 상태이기 때문에 생략하고 두 개의 서버를 동시에 시작해야하는데 concurrently 라이브러리를 사용했다.
"scripts": { "start": "node server.js", "heroku-postbuild": "cd frontend && npm install && npm run build", "dev": "concurrently \\"npm run dev:server\\" \\"npm run dev:client\\"", "dev:server": "node server.js", "dev:client": "npm start" },
설정을 맞추고 <code>npm run dev</code>을 실행했다. 이제 두 개의 서버가 동시에 실행되었다.
다음 frontend로 가서 빌드를 해보자. 하지만 빌드 이전에 또 Route 설정이 필요하다.
// 리액트 정적 파일 제공 app.use(express.static(path.join(__dirname, "frontend/build"))); // 라우트 설정 app.get("\\*", (req, res) => { res.sendFile(path.join(\\_\\_dirname + "/frontend/build/index.html")); });
ReferenceError: __dirname is not defined에러가 나왔다. Express에서 CommonJS에서 사용하던 __dirname 변수가 ES 모듈에서는 없기 때문에 발생하는 에러이다.
import path from 'path'; const __dirname = path.resolve();
해당 에러는 path 모듈로 루트 디렉토리를 지정하는 경로를 제공해줘서 해결해준다.
 
https://node-js.tistory.com/entry/Nodejs-dirname-is-not-defined-에러http://daplus.net/node-js-__dirname으로-path-join-vs-path-resolve/
다시 루트 디렉토리의 package.json에서 script 안에 추가했다.
"scripts": { "heroku-postbuild": "cd frontend && npm install && npm run build", }
그리고 다시 빌드를 실행했다. error: failed to push some refs to 'https://github.com/bpthess/e-commerce.git'>
헤로쿠에 어떤 버전의 nodejs 사용하고 있는지 알려줘야 한다고 한다. 배포 전 heroku가 지원하는 nodejs 버전도 잘 확인해야한다.
https://devcenter.heroku.com/articles/python-support
하위 디렉토리 runtime 파일 생성
$ nodejs-v16.15.0
다시 빌드해보자. 빌드에 성공했다. 이제 되는 것인가?
notion image
 
어떤 에러가 나오는지 알아보자
notion image
$ heroku logs --tail
해당 에러는 https://intrepidgeeks.com/tutorial/story-of-errors-in-designing-react-vite-with-heroku 링크에서 안내하는대로 시도해 봐야겠다.
at=error code=H10 desc="App crashed" method=GET path="/" host=e-commerce0001.herokuapp.com at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=e-commerce0001.herokuapp.com
 
notion image
 

댓글

guest