heroku로 nodejs서버와 react앱 배포하기

heroku 특성상 두개의 앱으로 배포하게되면 (하나는 api 하나는 client) 한쪽이 sleep 상태일 경우 응답시간이 오래걸리는데, 이를 방지하기 위해 하나의 앱에 백과 프론트를 통째로 넣어서 배포하는 방법이다.

서버와 클라이언트 합치기


원래 따로 분리되어 있던 api와 client를 api폴더 안에 client를 넣어서 합쳐준다.
나는 npm ERR! Error: EPERM: operation not permitted, rename 에러가 떠서
client폴더를 삭제하고npx create-react-app으로 리액트 앱을 api/client 경로로 새로 설치했다.

빌드 준비하기

빌드를 어떻게 할것인지 정해주고, 배포시 달라지는 경로들을 수정해줘야 한다.(localhost 같은것들..)

heroku 가입 후 새 앱 만들기

heroku 가입후 대시보드에서 Create a new app을 선택하여 새 앱을 만든다.

원하는 앱 이름을 지어주고 (이 앱 이름이 주소가 된다. ex) myapp.herokuapp.com )

포트번호변경

먼저 포트번호를 바꿔준다.

//api/index.js
const port = process.env.PORT || 5000;
app.listen(port, () => {
    console.log("success!")
});

이렇게 입력하면 heroku로 빌드시 알아서 포트경로를 잡아준다.

빌드 설정

다음엔 스테틱경로와 빌드경로를 client/build로 잡아준다.

//api/index.js
app.use(express.static(path.join(__dirname, "/client/build")));

app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, '/client/build', 'index.html'));
});

api의 package.json파일로 가서 heroku 명령어를 실행할 순서대로 정해준다.

/*api/package.json*/
  "scripts": {
    "start": "node index.js",
    "heroku-postbuild": "cd client && npm install && npm run build",
    "test": "nodemon index.js"
  },

axios instance로 단축주소 사용하기

client폴더로 이동해서 src폴더에 config.js파일을 만들고(파일명 무관) 엑시오스 인스턴스를 만들어 활용한다.

heroku 앱을 실행시키면 나오는 주소 + /라우터주소/로 기본주소를 설정한다.

//config.js
import axios from "axios"

export const axiosInstance = axios.create({
    baseURL: "https://iwipwq-nest.herokuapp.com/api/"
})

이제부터 모든 엑시오스 요청을 axiosInstance로 대체한다.

ex)

//...
//import axios from "axios";
import { axiosInstance } from "../../config";

//...
export default function Home() {
    const [posts, setPosts] = useState([]);
    const {search} = useLocation();
    const { user } = useContext(Context);
    useEffect(() => {
        const fetchPosts = async () => {
          //const res = await axios.get("http://localhost:5000/api/post" + search);
            const res = await axiosInstance.get("/post" + search);
            setPosts(res.data)
        }
        fetchPosts();
    },[search])
//...

PF 변경

이미지나 파일등 소스가 담길 퍼스널 폴더의 경로도 지정해준다.

//const PF = "https://localhost:5000/images
const PF = "https://iwipwq-nest.herokuapp.com/images/"

heroku 설치하고 빌드 배포하기

heroku cli를 설치한다.
npm install -g heroku

이걸로 설치해도 됨, 난 에러가 나서 64bit 인스톨러로 설치했다.

근데 노드 버전과 헤로쿠버전이 구버전으로 깔리길래 다시 git bash에서 cli로 설치하고
터미널을 재시작했다.

heroku --version으로 설치를 확인할 수 있으며 정책위반이 뜨는경우
스크립트 실행 권한 설정 를 참고해서 권한을 설정한다.

다음은 heroku login으로 heroku에 로그인한다.

아무키나 누르면 브라우저 창이 뜨면서 확인하라고 한다. 로그인 확인을 확인을 누른다.


로그인 완료

이제 깃 배쉬창에서 api폴더로 이동후 git init으로 깃을 초기화한다.

다음은 heroku git:remote -a heroku에서만든앱이름 으로 heroku 원격 리포지토리를 연결한다.

다음 명령어로 프로젝트를 커밋하고 푸쉬한다.
$ git add .
$ git commit -am "커밋메시지"
$ git push heroku master

package.json에 설정해놓은 heroku 스크립트 대로 빌드가 진행되는데 여기서부터 시간이 조금 걸린다.

빌드가 완료되었다면 이제 heroku 대시보드에서 settings 로 가서 Reveal Config Vars를 클릭해서 설정변수를 입력한다.

api의 .env에 작성해놓은 키와 밸류처럼 작성하면 된다.
MongoDB 연결을 위한 키와 벨류를 입력하고 ADD로 추가한다.

여기서도 적용되는데 시간이 약간 걸린다.
heroku 대시보드에서 openapp으로 빌드한 웹페이지를 열어보자.

앱 화면에서 이미지가 안보이길래 당황했는데,

여기서 이미지 폴더를 제외시켜서 그런거였다. 지우고 다시
$ git add .
$ git commit -am "커밋메시지"
$ git push heroku master

이제 정상적으로 작동한다.


최종 배포까지 끝났다... 중간에 이력서 급하게 쓴다고 기록을 다 못했는데, 나머지 과정도 기록해야겠다.

좋은 웹페이지 즐겨찾기