230104 fly로 배포할 때 겪었던 문제 정리(1)

샨티(shanti)·2023년 1월 4일
0
post-thumbnail

하루를 마무리 하기 전, 오늘 있었던 일들을 잔잔히 되짚어봅니다.
성공과 실패의 모든 요소에서 '배울 점'을 찾아내어 기록하고,
더 성장하는 내일의 나를 위해 'action plan'을 세웁니다.

프로그래머스 코딩테스트가 아닌 나름 정리된 TIL로 글을 쓰는 것이 오랜만이다.
할 일에 치이다보니 그럴 것이고, 한편으론 할 일을 미친듯이(ㅎㅎ) 쳐내지 못한 탓도 있으리라.

근 몇 주째 배포 때문에 너무 고생을 하고 애를 먹다가...
fly에 아주 소액이라도 투자하자는 마음으로 오늘 아침에 RAM을 올리고나니 기가맥히게, 느껴질만큼 빠른 속도. 이럴 줄 알았으면 진작 돈 좀 쓸걸 그랬어.

잊을만하면 주말 평일 할 것 없이 날아오던 memory crashed 이메일. 이제는 오지 않겠지? ㅎㅎ.
얼마 전만 해도 백엔드쪽 접속하면 매번 502 에러 뜨고 뭐 하나 빠르게 뜨는게 없었는데 이전에 비하면 정말 정말 속시원하게 느껴질만큼 속도가 빨라졌다.
혹 fly로 배포하려는 분들 계시다면 너무 고생하지 말고 scale 메뉴 들어가서 RAM을 512MB로 올리는 걸 강력 추천한다.
플랜 자체를 바꾸는 건 가격이 꽤 나가는걸로 아는데, 굳이 그렇게까지 하지는 않아도 되고 RAM만 조정해도 홧병이 치료되는.. 놀라운 일이.

anyway.

아직 배포에 익숙하지 않아 사실 속도 문제 뿐만 아니라 너무 다방면으로 문제를 겪었어서;; 여기 저기 터지는 곳 막기 바빴는데, 오늘은 뭔가 살짝 감이 잡히는 부분들이 있어서 잊기 전에 문제들을 정리해두려고 한다.

함께 공부하는 동료들 모두 동일한 상황이긴 하지만, 우리같은 경우 리액트 프로젝트를 생성할 때 CRA를 사용하여 빌드하지 않았다. 또한 parcel을 사용하고 바닥부터 빌드해서 앱을 만들었는데 그러다보니 인터넷에서 그나마 쉽게 접할 수 있는 정보들은 거의 적용되지 않아 꽤 오랜시간 삽질을 할 수 밖에 없었다. 그래도 여러 동료들의 도움을 받고 또 그 와중에 비슷한 상황에 처해있는 분들이 올리신 블로그 글로 해결한 것들이 있었다.

또한 나도 디버깅을 하면서 발견한 부분들이 있고 정말 창문 열고 나가야하나? 싶을 만큼 어이없는 실수들도 있어서 ㅎㅎㅎ.
언젠간 이 글을 들여다보며 '훗 귀엽군' 하고 웃을날이 오리라 기대하면서 정리해본다.


1. 어처구니 없는 baseUrl 실수

헤로쿠가 유료화되면서 이번에는 fly로 배포를 했다.
물론 일정부분 더 나은 환경을 누리려면 여기도 마찬가지로 결제를 해야 하지만...
갠적으론 배포 과정이 뭔가 fly가 좀 더 심플하게 느껴진달까..?

도대체 실무에선 어떻게 배포를 하는건가 싶지만.. 여튼 그건 취직해서 직접 부딪혀보기로 하고.

배포를 하면서 겪었던 문제중에 제일 어처구니 없고 지금도 창문 열고 나가고 싶은 부분. 바로 baseUrl 실수였다.

사건의 전말은 이랬다.

좌충우돌, 배포가 되긴 되어서 뭔가 홈 화면이 떴는데, 이상하리만큼 로그인이 되질 않았다.
로그인만 했다 하면 화면이 확 죽어버리고 나와야 할 컴포넌트가 아예 나오지 않는 현상의 반복.
대체 무슨일인가 어리둥절 하고 개발자 도구를 켜도 영 포인트를 잡기가 어려웠다.

결국 console.log()를 찍어가면서 디버깅을 하기 시작.
가장 무식한 방법인 것 같지만 사실 이렇게 확실한 방법도 없는 것 같다. 왜 진작 이 생각을 못했을까...

우선 로그인 성공/실패 여부와는 관계 없이 반드시 나와야 할 컴포넌트가 있었는데 그것 조차 렌더링되지 않는걸 보고는 서버에서 값을 받아오는 부분에 console.log()를 찍어보았다.

근데 개발자도구에서 확인한.. 말도 안되는 모습.

않이...

분명 나는 서버에서 받아온 데이터가 뭔지 궁금해서 찍었는데 갑자기 왠 index.html 파일의 모습이...?

이제 너마저 돌아버렸구나 싶어서 나도 정신이 혼미해지려는 찰나.

어...? 너 도대체 어디다가 뭘 요청하고 있는거니?

그리고 급하게 확인해 본 config 파일...
아.....

ㅋ.........................

baseUrl을 서버 주소로 해놨어야 했는데 너무나도 당당하게 front 프로젝트가 배포된 주소로 넣어둔 것이었다. local 주소에서 배포된 주소로 바꾸는 과정에서 저지른 실수였다.


잡았다 요놈.

process를 정확하게 이해하지 못한 상태에서 그저 과정만 따라가기에 급급하다보면 이런 실수가 드러나는 것 같다. 마음이 급해서 생긴 문제.

다시 정신을 차리고 baseUrl을 바꾸니 그제서야 제대로 나오는 화면.
정말 몇 주만에 멀쩡한 화면을 봐서 그런지 중병이 치료되는 느낌이었다.
너무 답답한 마음에 제대로 돌아가는 화면이라도 봐야겠다 싶어서 사실 local로 돌리고 있었던건 안비밀....

배포... 언제쯤 쉬워질래!!!!!ㅠㅠㅎㅎㅎ.
여튼 이런 이상하고도 정신나갈 것 같은 실수는 그만하자.


2. 특정 소셜 로그인만 작동하지 않는 문제

화면이 잘 뜨는 건 정말 다행스러운 일이었다. 그런데 역시 또다른 문제에 부딪혔다. 바로 특정 소셜 로그인만 제대로 작동하지 않는 문제가 발생한 것이다.

다시한번 상기해보지만... 로컬에선 그 어떤 문제도 일어나지 않았었다. (모두가 그렇겠지? ㅋㅋㅋ)
그러나... 아주 아주 아주 놀랍게도...
배포만 하면 정말 여기저기 터지지 않는 곳이 없다.

우선 나는 네이버와 카카오 소셜 로그인 기능을 가져와서 사용하고 있었는데.
로컬 환경에서 개발을 마친 후에 배포를 하면 이 소셜 로그인들이 정상적으로 작동할 수 있도록 추가 조치를 취해주어야 한다.

네이버는 네아로일거고, 카카오는 아마 개발자 페이지가 따로 있을텐데.
거기에서 로그인 API와 관련된 페이지에 가서 배포된 주소를 추가해주어야 배포된 환경에서도 로그인 기능이 잘 돌아간다.

코드 역시 수정이 필요한데, 특히 redirect 주소가 아마 local로 되어있을거고, 이걸 수정하지 않으면 계속 접근이 불가능한 페이지로 redirect를 시켜주기 때문에 배포하기 전에 꼭 해당 주소들을 모두 배포된 주소로 수정해주어야 한다.

나도 프론트와 백 여러곳에 퍼져 있는 주소들을 수정해주느라 꽤 애를 먹었다.
특히 .env 파일이나 properties에 숨겨놓은 줄 모르고 "왜 안돼!!!"를 외치다가 너무 늦게 발견하고는 엉엉 울며 바꾸기를 여러번...

제대로 바꾸지 않으면 수정할 때마다 배포도 다시 해주어야 하니 최대한 수정 완료 상태에서 배포하도록...! (실무에선 말할것도 없을 것이고..)


여튼, 나는 저 설정의 문제는 아니었고 요상하게 네이버 로그인은 제대로 돌아가는데 카카오 로그인만 계속 access token을 받아오지 못하고 실패해서 로그인을 받아오지 못하는 것이었다.

아무리 생각해도 이상했다.

우선
(1) 로컬 환경에선 전혀 문제가 없었고,
(2) 두 프로세스의 로직 또한 문제가 없는데,
(3) 카카오만 안될건 또 뭐람..?

하... 그래도 하나 하나 디버깅을 할 때의 유익함을 알아버렸기 때문에 이대로 시간만 흘려보낼 순 없어서 작정하고 문제점을 찾기 시작했다.

먼저 서버측에서 혹시 access token을 못보내고 있나? 싶어서 반환값을 확인해보았다.

찍어보니 액세스 토큰이 너무나도 멀쩡하게 잘 나오는 것이었다.


카카오 로그인을 시도할 때마다 너무나도 멀쩡하게 받아오던 액세스 토큰...

아참. fly 배포 후에 monitoring 메뉴를 통해 해당 로그들을 확인할 수 있으니 참고.

그럼 서버가 주는 값의 문제는 아니고... 다시 프론트로 와서...
이번엔 api 요청 후 데이터를 받아오는 쪽의 코드를 살펴보는데.

...어?

네이버와 카카오의 코드가 다르다.
어렴풋이 기억을 떠올려보니 axios를 사용할 때 instance로 만들어보라고 하신 아샬님의 말씀을 듣고 두 코드 중에서 카카오는 instance로 만들어서 사용해보고 naver는 그대로 두었던게 퍼뜩 기억났다.

// UserApiService.js
import axios from 'axios';
import config from '../config';

const baseUrl = config.apiBaseUrl;

export default class UserApiService {
  constructor() {
    this.accessToken = '';

    this.instance = axios.create({
      baseURL: baseUrl,
      timeout: 1000,
      headers: { Authorization: `Bearer ${this.accessToken}` },
    });
  }

  setAccessToken(accessToken) {
    this.accessToken = accessToken;
  }

  async sendKakaoAuthorizationCode(code) {
    const { data } = await this.instance
      .get('/oauth/kakao-token', { params: { code } });
    return data;
  }
  
  async sendNaverAuthorizationCode(code) {
    const url = `${baseUrl}/oauth/naver-token`;
    const { data } = await axios.get(url, { params: { code } });
    return data;
  }
}

우선 코드가 다르다는 것 까지는 발견을 했는데...
되는 상태부터 먼저 봐야겠다는 생각에 sendKakaoAuthorizationCode 내용을 naver와 동일하게 만든 다음에 실행해보니까 정상적으로 access token이 들어왔다.

그렇담 도대체 뭐가 문제일까... instance를 쓴 것 자체가 잘못인걸까...?

근데 함께 보던 동료가 상단에 있는 timeout의 정체를 잘 모르겠다고 했다.
그러게. 뭔가 알 듯 말 듯한 느낌에 문서를 찾아보았고 timeout에 설정된 시간 만큼 대기하고 그 시간 내에 요청이 처리되지 않았을 경우 error를 던진다는 것을 알게 되었다.

어??? 그럼 설마 요청 대기 시간을 너무 타이트하게 잡아줘서 이제껏 에러를 던지고 있었던거야?????

아차 싶은 마음에 이 요청에 대한 응답을 처리하는 store에 가서 try-catch 구문에서 받는 error에 콘솔을 찍어보고 급히 deploy를 해보았다.

결과는... 헐..

개발자 도구를 통해 확인해보니 예상이 맞았다.
타이트한 시간 세팅 때문에 계속 에러를 던지고 있었던 건데 그것도 모르고 이상한 것만 계속 확인하고 또 갈피를 못잡고 있었던 것이다.

instance를 만들 때 그 안에 들어가는 각각의 요소들이 어떤 역할을 하는지 정확하게 알았더라면 이런 문제를 겪진 않았을 것 같은데...
또 한편으론 의도찮게 네이버-카카오의 코드를 다르게 하는 바람에 뒷걸음질 치다가 뭐 잡은 격으로 배움의 기회를 얻을 수 있었다.

저 timeout을 10000으로 늘린 후 deploy를 하니 깔끔하게 성공하는 로그인.
아... 정말 생각지도 못한 난관을 겪었고 또 생각지도 못하게 배움의 기회를 얻은 날이었다.

배포 과정이 험난하긴 하지만 그래도 꽤 많은 것들을 배우는 것 같다.
자꾸 놓치지 말고 간략하게라도 기록하면서... 언젠간 배포가 좀 더 쉬워질 날이 오겠지? ㅎㅎ

네이버 검수도 얼른 잘 끝나서 사람들에게 내가 만든 애플리케이션이라고 보여주고 싶다...ㅎㅎ;

힘내보자. 화이팅!

profile
가벼운 사진, 그렇지 못한 글

1개의 댓글

comment-user-thumbnail
2023년 6월 21일

안녕하세요. 샨티님
개발 과정 공유 감사합니다. 꼼꼼히 정리해놓으신 내용에 도움 많이 받고 있습니다.
하나 여쭤보고 싶은 내용이 있는데,
메가테라 백엔드 생존코스 수강중이신가요? 혹은 웹개발자 입문 코스 수강하고 계신걸까요?

답글 달기