express nginx에 배포

천영석·2021년 9월 11일
0

nginx에 express를 배포했다. express는 노드 서버로 사용되고 있으며, 지금은 단순히 클라이언트의 index.html와 index.js를 가지고 메인 페이지에 맞는 데이터로 가공해서 전달해주는 역할을 하고 있다. 특별히 토큰을 받고, 사용자를 확인해 사용자에 알맞는 데이터를 가공하고 있지는 않다. 곧 할 예정이다.

다시 돌아와서, nginx에 proxy 설정을 통해 요청이 들어오면 express로 보내도록 했다.

location / {
proxy_pass http://127.0.0.1:3006;
}

블로그에는 각종 설정이 많았는데, 어떤 설정인지 잘 모르기도 하고 필요하지 않을 것 같아서 사용하지 않았다. 사용하는 이유를 알게 되면 사용하려고 한다.

이제 들어오는 요청은 모두 3006번으로 설정한 express의 서버인 3006번 포트로 연결된다. 3000번을 사용할까 하다가 3000번은 리액트에서 사용하고 있어서 3006번으로 했는데, 사실 상관 없는 것 같다. 다시 3000번으로 돌려야겠다.

이제 nginx에 설정되어 있는 root 폴더에 express를 빌드한 파일을 옮기기만 하면 됐다. 내 로컬에 있는 파일을 어떻게 옮겨야 할지 감이 안왔다. 구글링을 했고, scp 명령어를 통해 할 수 있다는 것을 알게 되었다. scp란 secure copy라고 한다. 몇 번 시도하다가 안돼서 백엔드에게 도움을 요청했는데, 바보같이 로컬에서 ec2로 옮기는 작업을 ec2에서 명령어를 계속 치고 있었다. 로컬로 넘어가서는 금방 해결됐다.

scp -i [pem file] [upload file] [user id]@[ec2 public IP]:~/[transfer address]

프론트가 사용하는 폴더는 dist이고, 노드 서버가 사용하는 폴더는 dist-server로 구분지었다. dist-server에 index.js를 할당했다. 이제 node index.js 만 하면 끝날 줄 알았다.

하지만 해당 명령어를 입력하자 모듈이 존재하지 않는다는 에러가 나왔다. 살짝 당황했지만 commonJS의 require은 동기적으로 동작한다는 것이 이런 뜻이구나... 라는 것을 느꼈다. 즉, 웹팩에서 target: node로 설정하고 빌드를 실행하면, 각종 필요한 모듈들이 require로 받아지고 있다는 것을 볼 수 있다. 즉, node 환경에서는 node_modules가 꼭 존재해야 한다는 것이다. 그래야 node_modules에 접근해서 해당하는 모듈을 가져와 사용할 수 있다.

기본 값인 target: web인 경우에는 빌드를 하면서 필요한 모든 모듈을 받아와서 하나의 코드로 만들어버린다. 그렇게 하지 않고 import로 그냥 둔다면 접근도 못할 뿐더러 브라우저에서 import는 script처럼 하나의 네트워크 요청으로 이어지기 때문에 엄청나게 많은 요청이 생길 것이다.

그래서 dist-server 폴더에 node_modules를 설치해줬고, 실행에 성공했다.

하지만 문제가 또 생겼다. 필요한 파일인 dist 폴더 안에 있는 index.html을 불러오지 못하는 것이다. 경로 설정이 잘못된 것이었다. 경로를 정확하게 표시하기 위해 __dirname을 사용했다.

__dirname에 대한 개념이 부족한 상태였는데, 이번 기회에 확실하게 알게 되었다. 파일이 존재하는 위치이다. 그리고 path.resolve로 경로를 합쳐주었다.

path.resolve(__dirname, '../dist/index.html');

resolve는 경로를 뒤에서부터 읽는다고 한다. 그리고 /폴더명을 만나면 즉시 종료한다고 한다. 즉 위에서 path.resolve(__dirname, '/dist/index.html'); 라면 경로는 /dist/index.html이 된다. 하지만 dist-server에는 dist폴더가 없기 때문에 문제가 발생할 것이다. 그래서 ../까지 넣어주었다.

join을 사용해도 똑같은 결과였을 것 같다. 하지만 확실하게 알지 못하고 resolve를 사용했다. 반성한다... join은 resolve처럼 빡빡하지 않고 조금 자비가 있는 것 같다. 절대경로를 만나도 다 합쳐준다.

즉, resolve는 절대경로, join은 상대경로이다.

이렇게 경로까지 무사히 등록했고, 실행이 잘 되면서 끝났다.

어? 파비콘이 없다. 이게 대체 무슨일이지? 분명 link태그에 파비콘을 등록해놨고, 서버에 favicon.png가 있는 것도 확인이 된다. 하지만 요청을 안한다. 이런 말도 안되는 상황에 난처해졌다.

구글링을 해보니 스택 오버플로우에 나와 같은 고민을 한 사람이 있었다. 하지만 완벽히 이해할 순 없었다.

https://stackoverflow.com/questions/34918906/no-request-for-favicon

크롬의 문제인지 뭔지 잘 모르겠다. 이 부분은 더 공부를 해봐야 할 것 같다. 도저히 이해가 안간다.😭😭😭 어쨋든 경로를 바꿔야 할 것 같다는 생각이 들었고, 이렇게 된 김에 favicon도 cdn으로 옮겼다. 그리고 동작은 매우 잘되고 있다. ec2를 끄기 전까진 잘되는 줄 알았다.

난 ec2에서 node를 실행해놓고 ec2를 종료해도 계속 실행이 되는 줄 알았다. 하지만 ec2를 종료하면 같이 서버도 꺼졌다... 조금 알아보니 24시간 서버를 유지하기 위해서는 pm2를 설치해야 했다.

pm2는 process manager의 약자로 노드 서버를 관리해주는 역할을 한다고 한다. 이해하기로는 노드 서버를 열어두면서 노드 서버에 어떤 요청이 들어왔고, 얼마나 많은 요청이 들어와 있는지와 같은 정보를 실시간으로 확인할 수 있다. 24시간 서버를 오픈하기 위해서는 pm2가 필요한 것 같았다.

pm2를 글로벌로 설치하고, pm2 start index.js 명령어만 입력하면 실행이 완료되었다. node.js는 싱글 스레드인데, pm2를 사용하면 멀티 스레드로 구동시켜준다고 한다. 무슨 말인지 사실 잘 모르겠다. 자바스크립트와는 완전 다른 세계인 것 같다... 얼른 이쪽 분야도 공부를 해야겠다고 절실히 느낀다.

이렇게 모든 설정을 마쳤고, 이제 서버에서 데이터를 받아와서 html을 구성해주는 코드만 작성하면 된다. 배포가 끝났으니 코드만 작성하면 돼서 마음이 편하다.

아직 젠킨스로 CD는 설정하지 않아서 두렵긴 하지만 어떻게 하면 잘 될 것 같다.

대략적인 프로세스는 다음과 같다.

botobo.kr 접속 ⇒ reverse-proxy 역할인 nginx에서 프론트 서버(nginx)로 연결 ⇒ 프론트 서버에서 또 reverse-proxy로 로컬 서버인 express 연결 ⇒ express에 접근해서 코드가 실행되고, index.html을 응답 ⇒ 역순

app.use(express.static(폴더))를 통해 express에 접근했을 때, 해당 폴더에 요청에 해당하는 파일이 있으면 보내준다.

profile
느려도 꾸준히 발전하려고 노력하는 사람입니다.

0개의 댓글