콘텐츠로 이동

로컬에서 시작해 서버를 세 번 옮긴 이야기

처음엔 제 노트북에서 돌렸습니다. 다음엔 “무료” 클라우드로 옮겼습니다. 결국엔 돈을 내는 작은 서버에 정착했습니다. 서버를 세 번 옮기면서 배운 건 단 하나입니다 — 인프라 선택의 진짜 비용은 가격표가 아니라 **“내가 거기서 얼마나 자주 싸우게 되는가”**라는 것. 이 글은 그 세 번의 이사를, 처음 개발하는 분도 따라올 수 있게 천천히 풀어 쓴 기록입니다.

그전에 — “서버”가 대체 왜 필요한가

섹션 제목: “그전에 — “서버”가 대체 왜 필요한가”

코드를 처음 짜는 분에게 “서버를 옮겼다”는 말은 추상적으로 들립니다. 그래서 먼저 용어부터 짚겠습니다. 우리가 만드는 건 회사 업무 시스템(ERP)입니다. 직원이 휴대폰으로 출퇴근을 찍고, PC로 결재를 올립니다. 그러려면 그들의 기기가 접속할 *“항상 켜져 있는 컴퓨터 한 대”*가 어딘가 있어야 합니다. 그게 서버입니다.

이 시스템은 1인 개발이고 아직 운영(실서비스) 전입니다. 그래서 지금 필요한 서버는 “실제 고객이 쓰는 운영 서버”가 아니라, 제가 매일 코드를 올려 돌려보는 개발 서버입니다. 이 구분이 글 전체에서 중요합니다 — 운영 데이터가 없으니 서버를 갈아엎어도 부담이 적었고, 덕분에 세 번이나 옮기는 실험을 할 수 있었습니다.

대부분의 프로젝트가 그렇듯, 처음엔 로컬(내 컴퓨터)에서 시작했습니다. 데이터베이스도, 백엔드도, 화면도 전부 제 노트북 안에 있었습니다. 이 단계는 빠르고 편합니다. 코드를 고치면 바로 옆 브라우저에서 결과가 보입니다. 누구 눈치 볼 것도 없습니다.

하지만 한계는 분명합니다. 제가 PC를 끄면 아무것도 안 돕니다. 모바일 앱으로 출퇴근을 찍어보려 해도, 휴대폰이 접속할 “바깥 주소”가 없습니다. 카페에서 노트북을 닫는 순간 동료의 테스트도 끊깁니다. 그래서 어느 순간 “어딘가 항상 켜져 있는 서버”로 이사해야 하는 시점이 옵니다. 저에게 그 시점은 모바일 출퇴근 앱을 실기기로 테스트하려던 때였습니다.

2단계 — “무료” 클라우드의 함정

섹션 제목: “2단계 — “무료” 클라우드의 함정”

다음 선택은 대형 클라우드의 무료 티어였습니다. 신용카드만 등록하면 일정 사양의 인스턴스(가상 서버)를 공짜로 준다는데, 안 쓸 이유가 없어 보였습니다. 실제로 그 클라우드용 마이그레이션(이전) 스크립트를 짜고, 해당 리눅스 배포판에 맞춰 설정을 새로 맞췄습니다.

문제는 “무료”의 대가가 시간이라는 점이었습니다. 무료로 주는 인스턴스는 메모리가 빠듯합니다. 그런데 ERP 규모의 프로젝트는 빌드 한 번에 메모리를 꽤 먹습니다. 결과는 빌드가 도중에 죽는 것 — 개발자들이 “OOM 났다”고 부르는 상황입니다.

메모리가 터지니, “어떻게든 터지지 않게” 우회하는 장치를 하나씩 끼워 넣게 됩니다. 커밋 기록에 그 흔적이 그대로 남아 있습니다.

  1. 회피 ① — 빌드 병렬 처리를 한 코어로 제한했습니다. 동시에 여러 작업을 돌리면 메모리가 더 터지니까요. 대신 느려집니다.
  2. 회피 ② — 테스트 파일을 빌드에서 제외했습니다. 빌드할 양을 줄여 메모리를 아끼려고요.
  3. 회피 ③ — 타입 검사를 건너뛰게 했습니다. 검사도 메모리를 먹으니까요.
  4. 회피 ④ — 그래도 안 되자, 아예 서버에서 빌드하길 포기하고 빌드 결과물을 제 PC에서 만들어 통째로 서버에 올렸습니다.

하나하나 보면 다 “합리적인 임시방편”입니다. 그런데 종합하면 기괴합니다. 본질은 기능 개발인데, 에너지의 대부분이 “이 빠듯한 환경에서 어떻게든 돌아가게 만들기”에 빨려 들어갔습니다. 타입 검사를 끄면 버그를 늦게 발견하고, 로컬 빌드를 올리면 “내 PC에선 되는데 서버에선 안 되는” 불일치가 생깁니다. 회피가 또 다른 문제를 낳는 악순환이었습니다.

빌드가 필요로 하는 메모리 vs 서버가 가진 메모리 무료 티어 서버 가진 메모리(작음) 빌드가 필요한 양 넘침 → OOM(빌드 사망) 서버 이전 적정 사양 서버 가진 메모리(여유) 빌드 필요량 여유 안에 들어옴 → 평범하게 빌드
무료 티어의 빠듯한 메모리(왼쪽)는 빌드가 필요로 하는 양을 넘겨 OOM을 일으킵니다. 적정 사양(오른쪽)으로 옮기자 같은 빌드가 여유 안에 들어와 평범하게 돌았습니다. 회피 코드 수십 개가 이 한 번의 이사로 사라졌습니다.

결국 합리적인 가격의 호스팅 업체로 옮겼습니다. 커밋 메시지에 남은 표현 그대로 이전의 목적은 단 한 줄, **“메모리 제약 제거”**였습니다. 화려한 기능을 위해서가 아니라, 빌드가 그냥 돌게 하기 위해서였습니다.

이전 직후 가장 먼저 한 일은 의외로 “되돌리기”였습니다. 그동안 메모리를 아끼려고 끼워 넣었던 회피 장치들을 하나씩 걷어내고, 서버에서 정상적으로 빌드하는 평범한 방식으로 복원했습니다. 커밋에 “서버 빌드 방식으로 전환”이라고 적혀 있습니다. 신기하게도, 빌드가 평범하게 도는 것만으로 개발 속도가 눈에 띄게 회복됐습니다. 특별한 최적화를 한 게 아닙니다. 싸움을 멈춘 것뿐입니다.

무료 티어에서 끼웠던 회피그게 만든 부작용이전 후
빌드를 한 코어로 제한빌드가 더 느려짐제한 해제 → 정상 속도
타입 검사 스킵버그를 늦게 발견검사 복원 → 조기 차단
로컬 빌드 결과물 업로드”내 PC선 되는데 서버선 안 됨”서버 빌드로 일원화

표를 보면 회피 하나하나가 또 다른 문제를 낳고 있었음이 드러납니다. 메모리를 아끼려던 장치들이 속도·품질·일관성을 갉아먹고 있었던 것입니다. 적정 사양으로 옮기자 이 부작용들이 한꺼번에 사라졌습니다.

단계어디서핵심 문제주로 쓴 시간
1단계내 노트북(로컬)끄면 멈춤 · 바깥 주소 없음기능 개발(좋음)
2단계무료 티어 클라우드메모리 부족 → OOM 반복회피 코드와 씨름
3단계적정 사양 서버(해소) 비용은 월정액다시 기능 개발

여기서 한 가지 분명히 해 둘 것 — 이 서버는 어디까지나 개발 서버입니다. 실제 운영은 향후 사내 환경에 별도로 구축할 계획이고, 지금 단계는 1인 개발이라 운영 데이터가 없습니다. 그래서 “서버를 옮긴다”는 결정도 부담 없이 내릴 수 있었습니다. 운영이 돌기 시작하면 이런 이사는 훨씬 무겁고 위험해집니다. 형태를 확정해 둘 거라면, 운영이 시작되기 전 지금이 가장 쌉니다.

되짚어 보면, 무료 티어에서 보낸 시간의 상당 부분은 “처음부터 적절한 사양을 골랐다면” 아예 없었을 비용이었습니다. 클라우드 무료 티어는 학습용·실험용으론 훌륭합니다. 리눅스를 만져보고, 배포를 연습하고, 작은 토이 프로젝트를 띄우기엔 최고입니다. 하지만 매일 빌드하고 배포하는 실제 개발 베이스로는 메모리가 발목을 잡기 쉽습니다.

그래서 다음에 비슷한 프로젝트를 시작한다면, 저는 처음부터 “내 빌드가 여기서 평범하게 도는가”를 첫 번째 기준으로 삼겠습니다. 사양은 화려할 필요 없습니다. 빠듯하지만 않으면 됩니다. 그 한 끗 차이가 매주 몇 시간을 좌우합니다.


이 글은 SL.AIMS를 만들며 겪은 현장 회고 중 하나입니다. 이 서버 위에서 어떤 DB·프록시·배포를 골랐는지는 〈DB를 무엇으로 할 것인가〉와 〈배포 자동화의 후회〉로 이어지고, 전체 그림은 〈사례연구: SL.AIMS〉에 있습니다.