서버는 항상 배포가 일이다..
남의 컴퓨터를 쓰는 일은 역시 쉽지 않다.
웹 프론트엔드 개발 후 vercel로 배포를 하면서 버튼 하나로 배포 되는 건 진짜 신세계다 생각하고 있었는데, 몇 달 전 서버에서는 heroku가 간편한 배포를 지원하고 있다는 걸 알게 되었다.
다양하게 커스텀하기에는 한계가 있지만 간편하게 서버를 띄우고 싶을 땐 꽤 유용하다. 무려 https로 배포해준다.
만약 헤로쿠가 처음이라면 여기로 들어가서 가입하면 된다.
바로 create new app을 눌러 앱을 생성한다.
만약 계정에 앱이 하나도 없는 상태라면 조금 더 큰 버튼으로 떴던 기억이 난다. 어떻게 생겼든 create new app이라고 쓰인 버튼을 눌러주면 된다.
앱 이름을 정하고 지역 설정을 해준다.
지역은 United States, Europe 두 개밖에 없어서 나는 미국으로 해줬다.
그 후 바로 Create app 버튼을 눌러준다.
무료계정에서 앱은 최대 100개까지 생성할 수 있다고 한다. (비인증 시 5개)
프로젝트 파일이 깃허브에 있다면 바로 연결해줄 수 있다. 가장 간편한 방법이다.
Deploy 탭에서 Deployment method를 보면 세 가지 옵션이 있는데,
그 중 GitHub을 클릭해준다.
Connect to GitHub 쪽을 보면 계정을 선택할 수 있다.
개인계정/organization 모두 선택 가능하다.
만약 원하는 organization이 보이지 않는다면, 아래 Ensure Heroku Dashboard has team access 버튼을 눌러 권한을 부여해준다.
버튼이 만약 Grant라면 내가 organization의 오너라 바로 권한을 부여할 수 있는 경우고, Request라면 나는 member라서 organization의 오너에게 대신 권한 허용 알림이 가게 된다.
권한 허용을 해주고 나면 해당 오가니제이션이 헤로쿠에서 성공적으로 읽힐 것이다.
원하는 오가니제이션 혹은 개인 계정을 선택해주고 서버 코드가 있는 repo-name을 검색한다.
레포를 찾았다면 Connect를 눌러준다.
성공적으로 연결되면 여러 설정을 할 수 있게 되는데,
develop 브랜치에 머지가 되면 자동으로 배포하는 옵션 (Automatic deploys)를 설정해주었다.
만약 github action 등으로 수행되는 CI 단계가 있다면 Wait for CI to pass before deploy 설정을 꼭 해주는 것이 좋다.
Manual deploy에서 특정 브랜치를 선택해 즉시 배포할 수도 있다.
만약 코드가 GitHub에 있지 않다면, CLI로 연결해줄 수 있다.
Deployment method에서 Heroku Git을 선택하면 방법이 안내되어 있다.
우선 Herocu CLI를 설치해줘야 한다.
맥을 쓴다면 terminal에서 brew tap heroku/brew && brew install heroku
명령어로 설치할 수 있다.
설치가 되었다면 terminal에서 heroku 로그인을 해주어야 한다.
heroku login
을 해서 시키는대로 하면 로그인이 된다. (브라우저에서 로그인을 시킬 것이다)
그 후 terminal에서 코드가 있는 곳으로 이동해서
heroku git:remote -a [앱 이름]
을 입력해준다.
여기서 [앱 이름]
은 우리가 헤로쿠에서 만든 앱 이름이다.
git으로 관리되고 있는 로컬의 코드를 헤로쿠 깃(리모트)와 연결하는 과정이다.
만약 로컬에 코드가 없다면 위 명령어 대신 heroku git:clone -a [앱 이름]
을 해주면 된다. 클론을 받아왔다면 cd [앱 이름]
명령어로 해당 폴더로 이동한다.
그런 후에는 헤로쿠 깃으로 푸시해주면 바로 빌드가 되는데, 푸시는 git push heroku master
로 간단히 할 수 있다.
만약 현재 로컬의 브랜치가 master가 아니라면 에러가 뜰 텐데, 그러면 git push heroku [현재 브랜치 이름]:master
명령어를 써주면 된다.
예를 들어 develop 브랜치에서 작업하고 있다면, git push heroku develop:mater
이런 식이다.
그럼 자동으로 빌드가 시작된다.
빌드에서 에러가 나도 괜찮다. 아직 자잘한 설정을 안 맞춰준 탓이다.
만약 여기까지 했는데 빌드가 되고 API 호출도 성공적으로 된다면 나는 정말 운 좋은 사람이다 세 번 외치고 뒤로가기 버튼을 누르면 된다.
Procfile은 헤로쿠 서버가 시작될 때 수행할 명령을 적어주는 파일이다.
루트에 파일을 만들어주면 된다.
상황에 맞게
web:node dist
나 web:npm start
를 해주면 된다.
뒤에서 node BuildPack을 추가해 줄 텐데, 빌드팩이 있으면 Procfile은 없어도 된다고 하니 넘어가도 된다.
헤로쿠 서버는 typescript를 처리하지 못한다.
그래서 tsc로 javascript 전환 후 dist 파일을 node로 컴파일 해야 한다.
// package.json
"scripts": {
"start": "node dist/server.js",
"build": "tsc",
"postinstall": "npm run build",
},
나는 이 조합을 선호한다.
빌드 시에 tsc
로 javascript로 전환하고,
start 시에 node dist/server.js
를 하는 방법이다.
dist
나 server.js
는 자신의 프로젝트에서 설정한 폴더/파일 이름을 넣어주면 된다.
postinstall이 중요한데,
postinstall을 생략하면 build 후에 멈춰버리는 현상이 생긴다.
tsc를 실행하고 아무것도 실행되지 않는 상태로 빌드가 얼어버리는 것이다.
꼭 postinstall 설정을 해주자.
(나는 프로젝트에서 yarn을 쓰고 있는데, 이상하게 yarn은 또 안 될 때가 있어서 heroku 서버에서는 npm run build를 해주고 있다.)
그 외에 엔진 버전(node, yarn 등)을 명시하라는 에러가 날 수도 있는데,
그럴 때는 package.json 최상단에 아래 코드를 추가해준다.
프로젝트 세팅에서 사용하는 버전에 맞게 써주면 된다. 대부분은 아래와 같을 것이다.
// package.json
"engines": {
"node": "16.x"
"yarn": "1.x"
},
Node를 쓰는 프로젝트는 빌드팩을 추가해주어야 한다.
터미널 해당 프로젝트 폴더 경로에서 heroku buildpacks:set heroku/nodejs
로 추가해줄 수 있다.
혹은 경로를 찾아가지 않고도 -a [앱 이름]
옵션을 줘도 된다.
추가된 노드 빌드팩은 헤로쿠 대시보드의 세팅에서 확인할 수 있다.
만약 프로젝트가 환경변수를 사용하고 있다면 (DB 정보 등) 헤로쿠에 이 정보도 등록해주어야 한다.
보통은 .env 파일을 gitignore 해 사용하지만, 헤로쿠에는 안타깝게도 파일을 올릴 수 없다. (ec2와 가장 크게 다른 점이다)
헤로쿠는 매번 푸시가 될 때마다 모든 파일을 덮어쓰기 때문에 서버 컴퓨터에 접속해 .env 파일을 등록했다고 하더라도 다음 빌드에서 삭제될 것이다.
따라서 사이트에서 하나하나 등록해주어야 한다. (구글에 찾아보면 다른 방법도 많았는데, 뭔갈 많이 설치해야 하고 잘 안 되는 경우도 많아서 나는 사이트에서 등록해주는 편이 가장 속 편했다)
헤로쿠 사이트 > 대시보드 > 우리가 쓰는 앱으로 들어가면,
Setting에서 Config Vars 항목을 볼 수 있다.
여기가 바로 환경변수를 등록해주는 곳이다.
Reveal Config Vars를 눌러서 key와 value를 각각 등록해주면 된다.
여기까지 따라왔다면 빌드를 한 번 해보자.
헤로쿠 깃의 브랜치로 푸시하면 바로 빌드가 진행된다.
git push heroku [현재 브랜치 이름]:master
명령어로 푸시할 수 있다.
빌드가 성공하면 빌드 성공이라는 메시지와 함께
배포된 링크도 함께 나온다.
API 호출 로그는 heroku logs --tail -a [앱 이름]
으로 확인해 볼 수 있다.
만약 terminal에서 해당 프로젝트 폴더 위치에 있다면 -a [앱 이름]
을 생략하고 heroku logs --tail
만 입력해도 된다.
이런 식으로 로그가 들어온다.
CLI로 빌드를 열심히 돌리다 보면 갑자기 계정에서 빌드 가능한 횟수를 초과했다는 에러가 나기도 한다.
당황하지 말고,
이전에 실행했던 빌드가 끝나지 않은 상태로 갇혀있거나 아직 빌드 진행 중인 경우에 이런 에러가 뜬다.
heroku builds:cancel -a [앱 이름]
으로 이전에 실행된 빌드를 강제 종료할 수 있다.