반응형


    요즘 웹앱 개발에 도전하면서 아마추어 개발자로 겪은 고충들을 나중에 다시 반복하지 않기 위해 글을 써둡니다.(나에게 쓰는 글이므로 이하 경어체)


    원래 heroku라는 서버 호스팅서비스를 쓰다가 아마존 웹 서비스(이하 aws)로 직접 서버 운영하려니 어려운점이 많다.

    내 웹앱은 node.js로 만들었고 github를통해 관리하고있다. db는 mlab이라는 mongodb서비스를 이용하다가 얼마전에 mongodb에서 mongodb atlas서비스를 출시해서 mongodb atlas로 이전했다.(무료티어 조건이 훨씬 좋다)

    오픈튜토리얼스 node.js 수업

    AWS의 서비스들이 뭔지부터 몰랐다

    aws를 들어가보면 서비스들이 너무많다.. 무엇부터 시작해야할지 막막해진다.

    다행히도 오픈튜토리얼스의 생활코딩 강좌에 aws강좌가 있어서 많은 도움이 되었다,

    생활코딩이 없었다면 웹개발을 시작조차 하지 못했을 것이다.

    aws강좌를 듣고 EC2서비스를 이용해 리눅스서버생성했고, Elastic IP를 이용해 고정아이피까지 발급, 연결시켰다.

    PuTTy를 통한 접속

    생황코딩대로 할 것을.. 후회하는 부분이다. 

    생활코딩과는 다르게 아마존에서 알려준 방식대로 PuTTy를 통해 서버에 접속하기로했다.

    다행히 아마존 한국어 도움말대로 하면 문제없이 접속할 수 있다.

    https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/putty.html?icmpid=docs_ec2_console

    접속후에는 git명령어로 내 앱을 불러오면된다.

    아래는 내가 사용한 명령어 예시이다.

    mkdir seatmaster

    cd seatmaster

    (디렉토리 만들고 그 디렉토리로 이동)

    git init

    (git 시작함, 이 때 원격저장소를 내 github주소를 입력)

    git pull

    (원격저장소에서 파일을 불러온다)

    node app.js

    (app.js 앱을 실행. 여기부터 문제가 생기는데..)


    node앞에 nginx사용하기

    서버를 직접 다루다보니 고려해야할점이 너무 많다. 

    node.js 웹서버를 80번 포트로 연결시켰더니 root권한으로 실행시켜야 정상작동한다. 하지만 내가만든, 보안이라고는 별 신경쓰지 않은 node 웹서버를 root권한으로 실행시키는것은 너무 위험한 짓인것 같다.

    구글링을 해보니 보통 가벼우면서도 많이 쓰는 전문웹서버인 nginx를 웹서버로 사용하고 프록시연결을 통해 localhost로 실행한 내 node.js웹서버로 연결을 시키는 방법을 많이 쓴다고 한다.

    해당내용은 node.js nginx proxy로 검색하면 한글, 영어자료 모두 풍부하다. http://blog.naver.com/kkh0879/220304643671 이 포스트를 많이 참조하였다. 

    node.js앱에서는 ip는 localhost 혹은 http://127.0.0.1로, 포트는 8080이나 3000같이 root권한이 필요없는 포트를 연결하도록 설정하면된다.

    환경변수

    heroku같은 서비스를 사용하면 process.env로 접근할수 있는 환경변수를 쉽게 설정할수 있는데, 리눅스 서버는 직접 설정해줘야한다.

    리눅스에서 환경변수 설정 명령어는 export 변수이름=값 이다. 처음에 많이 헤맨점은 등호(=) 앞뒤로 띄어쓰기가 들어가면 안된다는점이다.

    export명령어를 직접 실행하면 서버가 꺼지면 다 날아가므로 서버 시작시 환경변수가 설정될 수 있도록 bash.bashrc같은 파일 맨밑에 추가하고싶은 환경변수를 추가하면된다.

    자세한 내용은 이 포스트를 참조함 http://ngee.tistory.com/488

    http://repilria.tistory.com/411


    도메인연결

    도메인 연결은 letsencrypt로 ssl발급받기 전에 해야 ssl발급이 가능하다. 

    도메인 연결은 http://wingsnote.com/57 이 포스트를 참조했다.

    .

    https 접속을 위한 ssl letsencrypt

    https로 접속을 하려면 SSL을 발급받아야한다. SSL은 대부분 유료인데, letsencrypt에서 무료로 발급받을 수 있다.

    하지만 그다지 사용자친화적이진 않은 것 같다. 다시말해 좀 어렵다.

    https://blog.outsider.ne.kr/1178

    이 포스트를 많이 참조했다.


    https접속을위한 nginx프록시설정

    위에서 nginx프록시 설정을 했는데, https로 접속하려면 이부분을 다시 수정해줘야한다. 이부분은 제대로된 강좌가 별로 없어서 고생을 많이했다.

    현재 사용중인 프록시설정을 올려본다. http로 접속시 https로 이동시킨다. node.js는 3000번 포트를 보고있다.

    정적(static)파일은 node.js가 아니라 nginx에서 직접 서비스하고 지정된 public폴더안의 파일안에서 찾는다.

    upstream backend {

      server localhost:3000;

    }

    server{

      listen 80;

      server_name 서버주소;

      return 301 https://$server_name$request_uri;

    }

    server {

      listen 443 ssl;

      server_name 서버주소;


      ssl_certificate letsencrypt에서 ssl받을 때 알려주는 주소/fullchain.pem;

      ssl_certificate_key letsencrypt에서 ssl받을 때 알려주는 주소/privkey.pem;


      location / {

        root ~/프로젝트이름/public;

        try_files $uri @backend;

      }

      location @backend {

        proxy_pass http://backend;

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_set_header Host $host;

        proxy_header Upgrade $http_upgrade;

        proxy_set_header Connection 'upgrade';

        proxy_http_version 1.1;

        proxy_cache_bypass $http_upgrade;

      }

    }


    서버가 죽지않도록 forever

    node웹서버를  node app.js로 실행시킬 수 있지만 PuTTy로 접속중인 SSH연결이 끊어지면 바로 서버가 죽는다. 백그라운드에서 서버를 돌리려면 다른 프로그램을 써야하는데 나는 forever를 사용했다.

    npm install -g forever 로 설치할 수 있고

    실행은 forever start -m10 -w app.js

    이렇게 하면 app.js를 백그라운드로 실행하고 오류가 발생하면 최대 10번까지 재실행해주고 app.js에 변경사항이 있으면 다시 실행해준다.

    현재 실행중인 목록은 forever list로 확인할 수 있다.


    앞으로 해결해야 할 것

    이 밖에도 많은 고충이 있었지만, 대부분은 구글링을 통해 쉽게 해결이 가능했다.

    앞으로 해야할 것은 로그관리인데, 어찌해야하는지 감이 잡히질 않는다. 앱 자체가남기는 로그는 거의 없어서 이부분도 수정을 해야할 것 같고 nginx가 남기는 로그는 어떻게 확인하는지조차 잘 모르겠다. 더구나 익숙하지않은 리눅스환경에서 로그를 확인하는건 더 어려운 것 같다.

    그리고 나는 clustering에 대해 전혀 고려하지않고 웹앱을 만들었기 때문에 앞으로(만약에) 이용자수가 폭발해서 서버를 scale up할 상황을 전혀 생각하지 못했다. 내 앱은 socket.io가 중심으로 돌아가는데 여러대의 서버간의 소통은 아직 감이 잡히지 않는다. 지금까지 대충 알아본 바로는 redis를 이용해서 socket.io도 clustering이 가능하다고 하는데 redis서버를 따로 둬야하므로 경제적으로도 부담이되고, 아직까지는 심각하게 고민해볼 필요는 없을 것 같다.


    반응형
    Posted by 뭐하라