• Heroku에서 node.js 앱 배포 중 발생할 수 있는 PORT 관련 문제

    2022. 2. 3.

    by. 안녕진

    개인 공부 목적으로, 정확하지 않은 정보가 있을 수 있습니다.
    해결 방법만 필요하신 분은 해결 탭에서 확인해주시기 바랍니다.

    Heroku가 뭐지?

    대학교 공지사항 크롤러를 만들기 위해 flutter로 프론트를 만들고, express로 api서버를 구축하고 있었다.
    AWS 프리티어를 이용해서 우분투 서버를 만들어서 그곳에서 배포하려고 했는데, 프리티어라 그런지 자꾸 서버가 죽었다.
    그래서 로컬에서만 해보고 끝내려는데, 대학교 동기가 heroku라는 서비스를 알려줘서 이용해봤다.

    heroku에 관한 설명은 다른 블로그에 많으니 생략한다.
    서비스형 플랫폼(Platform as a Service, PaaS)을 찾아보면 된다.
    대충 서버를 직접 구축하는 등 앱을 배포하기 위한 플랫폼을 직접 구축할 필요 없이 배포를 돕는 것 같다.

    너무 매력적인 설명이라 바로 시도해 보았다.


    상황

    git push heroku master 명령으로 heroku에 앱을 배포했는데, 아래와 같은 오류가 났다.

    • 로그 중 일부 로그 상단을 보면 80번 port로의 접근이 원활하지 않은 것 같다.
    • 2022-02-03T06:20:52.171215+00:00 app[web.1]: 2022-02-03T06:20:52.171216+00:00 app[web.1]: Error: listen EACCES: permission denied 0.0.0.0:80 2022-02-03T06:20:52.171216+00:00 app[web.1]: at Server.setupListenHandle [as _listen2] (node:net:1317:21) 2022-02-03T06:20:52.171216+00:00 app[web.1]: at listenInCluster (node:net:1382:12) 2022-02-03T06:20:52.171216+00:00 app[web.1]: at Server.listen (node:net:1469:7) 2022-02-03T06:20:52.171217+00:00 app[web.1]: at Function.listen (/app/node_modules/express/lib/application.js:618:24) 2022-02-03T06:20:52.171217+00:00 app[web.1]: at Object.<anonymous> (/app/index.js:18:5) 2022-02-03T06:20:52.171217+00:00 app[web.1]: at Module._compile (node:internal/modules/cjs/loader:1101:14) 2022-02-03T06:20:52.171217+00:00 app[web.1]: at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10) 2022-02-03T06:20:52.171218+00:00 app[web.1]: at Module.load (node:internal/modules/cjs/loader:981:32) 2022-02-03T06:20:52.171220+00:00 app[web.1]: at Function.Module._load (node:internal/modules/cjs/loader:822:12) 2022-02-03T06:20:52.171220+00:00 app[web.1]: at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) 2022-02-03T06:20:52.171221+00:00 app[web.1]: Emitted 'error' event on Server instance at: 2022-02-03T06:20:52.171221+00:00 app[web.1]: at emitErrorNT (node:net:1361:8) 2022-02-03T06:20:52.171221+00:00 app[web.1]: at processTicksAndRejections (node:internal/process/task_queues:83:21) { 2022-02-03T06:20:52.171221+00:00 app[web.1]: code: 'EACCES', 2022-02-03T06:20:52.171221+00:00 app[web.1]: errno: -13, 2022-02-03T06:20:52.171222+00:00 app[web.1]: syscall: 'listen', 2022-02-03T06:20:52.171222+00:00 app[web.1]: address: '0.0.0.0', 2022-02-03T06:20:52.171222+00:00 app[web.1]: port: 80 2022-02-03T06:20:52.171222+00:00 app[web.1]: } 2022-02-03T06:20:52.317639+00:00 heroku[web.1]: Process exited with status 1 2022-02-03T06:20:52.357644+00:00 heroku[web.1]: State changed from starting to crashed

    문제 이해

    heroku에서 배포하면 웹에서 접속할 수 있도록 링크를 주다보니, 당연히 80 포트를 이용하는 줄 알았다.
    일단 포트에 문제가 생긴 것 같으니까, heroku docs에서 get started를 자세히 살펴보니 port 설정에 관한 부분을 찾을 수 있었다.
    그 결과 process.env.PORT와 같은 형태로 PORT를 이용해야 한다고 나왔고, 그렇게 해결했다.

    그럼 process.env는 뭘까?

    process.env

    일단 env(environment)라는 부분에서 알 수 있듯이, env는 환경변수라는 뜻이다.
    환경변수는 무엇일까?

    환경변수

    정확한 설명들은 구글에 더 자세히 나와있다.
    내가 이해한 환경변수는 프로그램이 돌아가는 환경(운영체제)에서 지정한 변수이다.
    그래서 같은 프로젝트라도, 환경변수를 이용하면 각 환경에 맞게 동작할 수 있는 것이다.
    예를들어 서버가 열릴 포트가 저장된 PORT라는 환경변수를 내 로컬에서는 80으로 지정해놨고, heroku에서는 3000으로 지정했다고 하자.
    그럼, 내 컴퓨터에서 실행될 때 process.env.PORT 는 80일것이고, heroku에서는 3000인 것이다.
    heroku가 어떤 방식으로 PORT를 설정하는지는 모르겠지만, 상황을 봐서 알맞은 (사용중이 아닌) 포트를 내게 제공해줄 것이다.
    실행할 때마다 바뀔 수 있는 실행 포트를 사용자가 직접 숫자로 입력할 필요 없이, 환경변수로 간단하게 접근하도록 하는 것이라고 이해했다.


    해결

    port 설정 부분을 다음과 같이 변경한다. const port = process.env.PORT || (로컬 서버 포트);

    댓글