SPACE LOGBOOK

OCEAN LOGBOOK

웹앱이 탄생한 순간부터…

2026.07.15

웹앱이 탄생한 순간부터…

2026.07.15
2026.07.15 · 새솔CRM 운영일지

웹앱은 만드는 순간이 아니라, 태어나는 순간이다

오늘 하루는 코드를 한 줄도 새로 짜지 않았다. 그런데도 가장 많이 배운 하루 중 하나였다. 의존성 5개를 업데이트했을 뿐인데, 그 과정에서 diff가 뭔지, npm install이 정확히 무슨 일을 하는지, GitHub가 나 같은 1인 개발자에게 왜 이렇게까지 퍼주는지를 다시 생각하게 됐다.
#개발일지#오픈소스#새솔CRM#GitHub

세무사가 본업인 내가 새솔CRM이라는 웹앱을 처음 만들기 시작했을 때, 목표는 단순했다. “고객 문서 발송, 좀 더 편하게 하자.” 그게 다였다. 완성하면 끝인 줄 알았다. 그런데 6개월 가까이 이 앱을 돌리면서 깨달은 게 하나 있다. 웹앱은 완성되는 물건이 아니라, 태어나서 계속 자라나는 무언가라는 것.

1. 내가 만든 게 아니라, 빌려 쓰고 있었다는 자각

새솔CRM의 package.json을 처음부터 끝까지 들여다본 날이 있었다. 서버 프레임워크 express, DB 드라이버 better-sqlite3, 비밀번호 암호화 bcryptjs, PDF 생성 puppeteer, 이메일 발송 nodemailer… 세어보니 직접 의존성만 21개가 넘었다.

그 순간 이상한 기분이 들었다. 나는 이 앱을 “내가 만들었다”고 생각하고 있었는데, 사실 코드의 대부분은 내가 짠 게 아니었다. 나는 전 세계 어딘가의 개발자들이 만들어놓은 부품들을 가져다가, 그걸 세무 업무에 맞게 조립한 것뿐이었다. 내 코드는 그 부품들을 이어붙이는 접착제에 가까웠다.

그리고 그 부품들 하나하나는, 나와 아무 상관 없는 이유로 계속 바뀌고 있었다. 보안 취약점이 발견되고, 새 버전이 나오고, 예전 버전은 서서히 뒤처져 갔다. 내가 신경 쓰지 않는 사이에도 말이다.

2. 그래서 세운 두 개의 감시탑

“내가 만든 게 완성됐다”는 착각에서 벗어나니, 다음 질문이 자연스럽게 따라왔다. 이 부품들이 낡아가는 걸 나는 어떻게 알아차릴 것인가? 매번 21개 라이브러리 버전을 손으로 확인하는 건 현실적이지 않았다. 그래서 두 개의 자동 감시 체계를 세웠다.

🔔 UptimeRobot — “서비스가 죽었을 때”

5분마다 나의 웹사이트에 접속해보고, 응답이 없으면 즉시 이메일로 알려주는 무료 모니터링 서비스. 라이브러리 문제든, 서버 문제든, 결과적으로 CRM 접속이 안 되는 순간을 바로 알 수 있게 됐다.

🤖 GitHub Dependabot — “부품이 낡아갈 때”

GitHub 저장소에 설정 파일 하나를 커밋하자마자, GitHub가 알아서 내 21개 라이브러리를 스캔해서 “이거 새 버전 나왔어요”라는 요청서(PR)를 자동으로 만들어주기 시작했다. 보안 취약점이 있으면 더 적극적으로 알려준다. 내가 매번 물어보지 않아도, 시스템이 먼저 손을 든다.

이 두 개를 세워놓고 나니 비로소 마음이 놓였다. 더 이상 “지금 이 라이브러리 괜찮은 건가” 하고 매번 스스로에게 물을 필요가 없어졌다. 물어보는 역할을 시스템에게 넘긴 것이다.

3. 실제로 겪어본 업데이트, 생각보다 간단하지 않았다

Dependabot이 만들어준 요청서 5개 중, bcryptjs와 helmet은 메이저 버전업이었다. 겉으로는 숫자 하나 올라가는 것처럼 보이지만, 실제로는 코드 내부 사용 방식과 부딪히는지 하나하나 확인해야 했다. 특히 puppeteer는 새 버전이 모듈 방식 자체(CommonJS → ESM)를 바꿔버려서, 그대로 올렸다가는 계약서 PDF 발급 기능이 통째로 멈출 뻔했다.

패키지결과이유
@anthropic-ai/sdk✅ 반영사용 중인 모델 그대로 유지, 영향 없음
bcryptjs✅ 반영메이저 업이지만 실사용 API는 안전 확인
better-sqlite3✅ 반영패치 버전업, 문제 없음
helmet✅ 반영보안 강화 방향, 프로젝트 설정과 충돌 없음
puppeteer⏸ 보류ESM 전환으로 PDF 생성 기능 전면 장애 위험

이 표를 만들면서 다시 한번 느꼈다. “업데이트”는 버튼 한 번 누르는 일이 아니라, 매번 작은 판단들의 연속이라는 걸. 그리고 그 판단을 위해 서버 상태를 확인하고, 영향 범위를 뜯어보고, 안전한지 검증하는 과정 자체가 결국 하나의 작은 프로젝트였다.

4. 근데 이 모든 걸, GitHub는 왜 공짜로 해줄까

Dependabot도, 보안 취약점 알림도, 무제한 저장소도 — 나 같은 1인 개발자는 단 한 푼도 내지 않는다. 처음엔 “그저 고맙다” 정도로 넘겼는데, 곰곰이 생각해보니 이건 순수한 자선이 아니었다.

GitHub의 진짜 자산은 서버 공간이 아니라 “전 세계 개발자가 여기 다 모여있다”는 사실 그 자체다. 내가 오늘 업데이트한 express, helmet, bcryptjs 같은 오픈소스 패키지들도 전부 GitHub 위에서 관리되고 있다. 만약 GitHub가 무료 유저를 다 쳐낸다면, 이 생태계 자체가 무너지고, 결국 돈을 내는 기업 고객들도 남을 이유가 없어진다.

그러니까 나 같은 무료 유저는, 지금 당장 돈이 안 되더라도, 이 생태계가 계속 살아있게 만드는 존재인 셈이다. 그리고 그중 일부는 팀이 생기고 회사가 커지면서 자연스럽게 유료로 넘어간다. 나를 노려서가 아니라, 이 구조 전체가 그렇게 설계되어 있다.

Dependabot 같은 보안 기능을 특히 아낌없이 풀어놓는 이유도 비슷하다. 오픈소스 패키지 하나에 취약점이 생겼을 때, 그걸 쓰는 수백만 개의 프로젝트가 빠르게 패치되어야 GitHub 생태계 전체의 신뢰도가 유지된다. 이건 개별 유저 하나를 붙잡으려는 영업이 아니라, 숲 전체를 건강하게 유지하려는 투자에 가깝다.

✦ ✦ ✦

5. 웹앱은 무생물이 아니다

오늘 하루를 정리하면서 든 생각은 하나였다. 웹앱은 물건이 아니라 유기체다.

처음 만들 때는 그냥 잘 만들면 끝이라고 생각했다. 기능 붙이고, 버그 잡고, 배포하면 완성이라고. 그런데 실제로는 아니었다. 완성된 순간부터 이 앱은 바깥 세상과 계속 연결된 채로 숨을 쉬기 시작했다. 내가 가만히 있어도, 이 앱을 구성하는 부품(라이브러리)들은 계속 나이를 먹는다. 어딘가에서 보안 구멍이 발견되고, 새 버전이 나오고, 예전 버전은 조용히 낡아간다. 서버는 새벽에도 혼자 크래시가 나기도 하고, PM2가 그걸 알아서 되살리기도 한다. 나는 자고 있는데, 이 앱은 혼자서 숨쉬고, 가끔 기침도 하고 있었던 거다.

그래서 지금은 이렇게 생각한다. 웹앱을 만드는 건 아이를 낳는 것과 비슷하다고. 낳는 순간이 끝이 아니라 시작이고, 그다음부터는 계속 돌보고, 자라는 걸 지켜보고, 아플 때 알아차리고, 시대에 맞게 배워나가게 해야 한다. 리팩토링은 성장통이고, 라이브러리 업데이트는 예방접종이고, UptimeRobot과 Dependabot은 이 아이가 아플 때 나에게 신호를 보내주는 감각기관 같은 거다.

완성이라는 개념 자체가 어쩌면 착각이었을지도 모른다. 살아있는 것에는 “완성”이 없다. 그저 오늘도 건강하게 살아있느냐, 다음 위협에 대비가 되어 있느냐만 있을 뿐이다.

1인 개발자로 세무 업무와 코드를 같이 붙잡고 있다 보면, 가끔 “이 정도면 이제 손 뗄 때 됐나” 싶은 순간이 온다. 근데 오늘 다시 느꼈다. 손을 뗄 수 있는 종류의 일이 아니었다. 이 앱이 살아있는 한, 나는 계속 옆에서 지켜보고 있어야 한다. 그게 부담스럽다기보다는, 이제는 조금 다르게 느껴진다. 매일 자라나는 걸 지켜보는 일이라고.

내가 만든 CRM앱을 만들고, 여전히 키우고 있습니다.

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

이 기록은 여기까지지만,
생각은 아직 이동 중이다