heroku 배포
학원 수업 Day36
node-express 로 구축해서 DB를 연결한 동적인 페이지는 github에 배포할 수 없으므로 Heroku 를 이용했다.
Heroku
헤로쿠는 여러 프로그래밍 언어를 지원하는 PaaS(Platform as a Service, 서비스로서의 플랫폼) 이다.
여기서 PaaS 가 무엇인지 궁금해졌다.
원래 직접 만든 App 을 다른 사람도 볼 수 있게 하려면 서버 컴퓨터를 세팅 해 두어야 그곳에 저장된 데이터를 볼 수 있었다.
하지만 최근에는(사실은 내가 모르는 오래 전 부터) 클라우드 컴퓨팅 서비스를 통해, 하드웨어나 소프트웨어 등의 자원을 직접 소유하지 않고 업체에서 제공하는 자원을 이용할 수 있게 되었다.
그리고 이 서비스는 제공/이용하는 자원의 범위에 따라 크게 SaaS, IaaS, PaaS 로 분류한다.
SaaS
Software as a Service
모든 하드웨어와 소프트웨어가 세팅이 되어 있어서 사용자는 이미 만들어진 소프트웨어만 이용할 수 있는 서비스이다.
풀옵션인 집에 내 짐만 보관하고 꺼내는 형태이다.
대표적으로 네이버 클라우드, 드롭박스 등이 있다.
IaaS
서버, 스토리지 등 하드웨어 자원을 제공해서 하드웨어부터 이용할 수 있는 서비스이다.
땅을 임대받아 내 마음대로 집을 짓고 사는 형태이다.
아마존의 AWS 가 대표적인 IaaS 라고 한다.
PaaS
하드웨어적인 세팅은 업체에서 미리 해 두고, 해당 하드웨어에 맞는 소프트웨어를 사용자가 직접 개발, 구축해서 이용할 수 있는 서비스이다.
지어진 집을 임대 받았지만 인테리어는 내가 원하는대로 하고 사는 형태이다.
지금 이용할 Heroku 가 PaaS 이다.
Heroku 는 Node.js, Ruby, Java, PHP 등의 언어로 만들어진 소프트웨어를 설치, 배포 할 수 있도록 지원한다.
사용자는 환경, 보안 등을 신경 쓸 필요 없이 해당 언어로 만들어진 소프트웨어만을 설치해 사용하면 된다.
내가 만든 페이지는 node.js 로 구동되므로 배포용으로 적합했다.
(하지만 Heroku 서비스가 11월 중순 이후부터 유료화 된다고 한다..)
heroku cli
heroku cli 에서 cli 는 Command Line Interface 로 텍스트 형태로 heroku 에 연결, 배포, 관리할수 있도록 하는 인터페이스이다.
터미널에서 아래 명령어로 heroku cli를 설치한다.
brew tap heroku/brew && brew install heroku
config Vars
Heroku 사이트 내 Settings 탭의 Config Vars 메뉴에서 공개되면 안되는 비밀번호, App Key 등을 환경변수로 설정한다.
App 내에서 process.env.이름
의 형태로 해당 값을 불러올 수 있다.
MongoDB 접속 정보를 가리기 위해 해당 URI 를 환경변수 MONGO_URI key 의 값으로 설정했다.
환경 변수 설정
개발중인 node 폴더 안에 config 폴더를 만들어서 dev.js, product.js, key.js 파일을 생성한다.
key.js 파일에서 배포상태인지 개발상태인지를 인지해 개발버전에서는 dev.js를 배포버전에는 product.js를 실행하도록 한다.
if (process.env.NODE_ENV === 'production') {
//배포상태
module.exports = require('./product.js');
} else {
//개발상태
module.exports = require('./dev.js');
}
dev.js, product.js 각각의 파일을 설정한다.
product.js 파일은 배포용이므로 환경변수 process.env.MONGO_URI를, dev.js 파일에는 실제 URI를 넣는다.
module.exports = {
mongoURI: process.env.MONGO_URI
}
그리고 이 key.js 를 node 의 index.js 파일 최상단에 불러온다.
const config = require('./config/key.js');
mongoose 에 연결하는 URI 부분에 해당 값을 사용한다.
app.listen(port, ()=>{
mongoose
.connect(config.mongoURI) // 기존 직접적인 URI 에서 수정
...
});
폴더 구조 변경
기존에는 하나의 프로젝트 폴더에 node, react 폴더를 따로 생성해서 back-end와 front-end 파일을 분리했지만, Heroku 배포를 위해 하나의 App 으로 합쳐야 한다.
-
node 폴더를 App 폴더로 변경한다.
-
react 폴더를 App 폴더 안으로 이동시킨다.
-
App 내부에 server 폴더 생성 후, index.js 와 package.json, package-lock.json 을 제외한 나머지 back-end 용 폴더(config, model, router)를 server 폴더로 넣는다.
결국 App 내부에 index.js, package.json, package-lock.json 파일과 react, server 폴더와 back-end 용 node_modules 가 있게 된다.
각 폴더의 위치가 바뀌었으니, react 의 node_modules 가 업로드 되지 않도록 .gitignore 를 수정한다.
이 때 /App/server/config/dev.js 의 mongoDB 연결 URI 도 노출되지 않아야 하므로 해당 경로도 추가한다.
index.js 에서 불러오는 파일들의 경로 또한 수정해야 한다.
node 구동 설정
package.js
nodemon을 사용하면서 start 명령어를 지정해 주었던 것을 다시 node 로 수정한다.
...
"start": "node index.js"
...
Procfile
App 폴더 내부에 Procfile (확장자 없음) 파일을 아래와 같이 생성한다.
web: node index.js
index.js
포트 번호가 Heroku에 의해서 지정이 되므로 환경변수 값으로 설정한다.
환경변수 비어있으면 8888 으로 열리도록 설정했다.
const port = process.env.PORT || 8888;
배포
먼저 heroku 에 로그인한다.
아래 명령어를 입력하면 브라우저에서 로그인 화면이 출력된다.
로그인 후 다시 terminal로 돌아온다.
heroku login
react 폴더에서 아래 명령어를 실행해서 빌드한다.
npm run-script build
App 외부, .gitignore 가 있는 프로젝트의 root 폴더에서 아래 명령어를 실행한다.
git init
git add .
git commit -m '메세지'
heroku git:remote -a 프로젝트 이름
git subtree push --prefix App heroku main
배포가 완료되면 https://프로젝트 이름.herokuapp.com 으로 접속이 가능하다.
수정 후 재배포
수정 작업을 완료했다면 다시 빌드해서 배포한다.
- react 폴더에서 빌드한다.
npm run-script build
- root 폴더로 이동해 모두 커밋한다.
git add .
git commit -m '메세지'
- 재배포한다.
git subtree push --prefix App heroku main
not found 에러
빌드 후 배포를 완료했는데 자꾸 not found가 나와서 뭐지 싶었다.
알고보니 빌드 시 github에 매번 파일이 올라갈 필요가 없어서 .gitignore 에서 build 폴더를 추가해뒀더니 heroku에서도 안올라가서 발생한 오류였다.
build 폴더를 업로드 제외 리스트에서 빼서 업로드 되도록 해야한다.