개발 프로젝트/[외주 프로젝트] 첫 외주 웹사이트 제작기: 기획부터 배포까지

왜 Next.js와 Spring Boot를 썼나

namerong 2026. 6. 12. 21:49

외주 프로젝트를 진행하면서 가장 많이 고민한 부분 중 하나는 기술 스택이었다.

처음부터 거창한 시스템을 만들 계획은 아니었다.
클라이언트가 원하는 것은 기본적으로 회사 소개, 서비스 안내, 견적 확인, 문의로 이어지는 홈페이지였다.
그래서 초반에는 최대한 단순하게 만들 수 있는 방법을 먼저 생각했다.

하지만 기능을 하나씩 정리하다 보니 단순한 정적 홈페이지로 끝내기에는 부족한 부분들이 보이기 시작했다.
견적 옵션은 쉽게 수정되어야 했고, 후기는 사용자가 직접 작성할 수 있어야 했으며,
관리자 페이지에서는 후기 관리와 통계 확인도 필요했다.

결국 이 프로젝트는 “보여주기만 하는 홈페이지”가 아니라, 실제 운영을 전제로 한 작은 서비스에 가까워졌다.

처음에는 서버리스와 스프레드시트만 생각했다

처음에는 백엔드를 따로 만들지 않는 방향도 고려했다.

이유는 단순했다. 비용을 최대한 줄이고 싶었고, 클라이언트가 개발자가 아니기 때문에 가격이나 옵션을 수정할 때 코드 수정 없이 직접 관리할 수 있어야 했다.

특히 견적 옵션은 자주 바뀔 수 있는 데이터였다.
예를 들어 도우미 인원, 수의, 관, 차량, 서비스 옵션처럼 금액이 붙는 항목들은 관리자가 쉽게 수정할 수 있어야 했다.

그래서 초반에는 Google Sheet를 데이터베이스처럼 사용하는 구조를 생각했다.

구조는 대략 이런 방식이었다.

Google Sheet에 옵션 데이터 입력
-> 프론트에서 Google Sheet API 호출
-> category, name, price 값을 읽어 화면에 select 박스로 표시
-> 사용자가 옵션 선택
-> 총 견적 금액 실시간 계산

이 방식의 장점은 명확했다.

Google Sheet는 누구나 수정하기 쉽고, 별도의 관리자 페이지 없이도 가격 변경이 가능하다.
서버 비용도 들지 않고, 복잡한 데이터베이스 관리도 필요 없다.

그래서 “견적 계산기만 있는 사이트”였다면 이 방식으로도 충분했을 수 있다.

하지만 기능이 늘어나면서 백엔드가 필요해졌다

문제는 프로젝트 범위가 점점 구체화되면서 생겼다.

견적 계산 기능 외에도 후기 작성 기능이 필요해졌고, 관리자가 후기를 삭제하거나 통계를 확인할 수 있는 기능도 필요해졌다. 이때부터는 단순히 Google Sheet만으로 처리하기 어려운 부분들이 생겼다.

후기 기능만 봐도 저장해야 할 데이터가 많다.

이름
비밀번호
후기 내용
작성 시간
삭제 여부

사용자는 계정 없이 후기를 작성하지만, 본인이 정한 비밀번호를 입력해야 삭제할 수 있어야 했다.
이 말은 비밀번호를 안전하게 저장하고, 삭제 요청이 들어왔을 때 검증하는 로직이 필요하다는 뜻이었다.

관리자 기능도 마찬가지였다.

관리자는 전체 후기를 확인하고 삭제할 수 있어야 했고, 사이트 방문이나 견적 사용 횟수 같은 간단한 통계도 확인할 수 있어야 했다.

이런 기능들은 프론트엔드만으로 처리하면 보안상 좋지 않다.
예를 들어 관리자 비밀번호나 DB 연결 정보가 프론트 코드에 들어가면 그대로 사용자에게 노출될 수 있다.

그래서 이 시점부터 백엔드가 필요하다고 판단했다.

정리하면 백엔드가 필요했던 이유는 다음과 같다.

후기 데이터를 안정적으로 저장해야 함
사용자 삭제 비밀번호를 검증해야 함
관리자 권한이 필요한 API가 필요함
방문/견적 사용 통계를 기록해야 함
민감한 정보는 프론트에 노출되면 안 됨

처음에는 단순한 홈페이지처럼 보였지만, 실제 운영 기능이 들어가면서 서버와 DB가 필요한 구조로 바뀐 것이다.

프론트엔드는 Next.js를 선택했다

프론트엔드는 Next.js를 사용했다.

이 프로젝트는 검색 노출도 어느 정도 고려해야 했고, Vercel 배포와의 궁합도 중요했다.
단순 React 프로젝트로도 충분히 만들 수는 있었지만, 페이지 단위 라우팅, 메타데이터 설정, 배포 편의성을 생각하면 Next.js가 더 적합하다고 판단했다.

Next.js를 선택한 이유는 크게 네 가지였다.

페이지 라우팅 구조를 잡기 쉽다
SEO 메타데이터 설정이 편하다
Vercel 배포가 간단하다
추후 페이지가 늘어나도 구조 관리가 쉽다

실제로 이 프로젝트에는 홈, 서비스, 견적문의, 후기, 자주 묻는 질문, 관리자 페이지가 필요했다.
이런 페이지들을 명확하게 나누고 관리하기에 Next.js의 App Router 구조가 잘 맞았다.

또한 네이버 서치어드바이저 등록을 위해 title, description, Open Graph, robots.txt, sitemap.xml 같은 설정도 필요했는데, Next.js에서는 이런 SEO 관련 설정을 비교적 자연스럽게 처리할 수 있었다.

백엔드는 Spring Boot를 선택했다

백엔드는 Spring Boot를 사용했다.

솔직히 말하면, 이 정도 규모의 프로젝트라면 Node.js로도 충분히 만들 수 있다.
더 빠르게 만들려면 Next.js API Route만으로도 일부 기능은 구현할 수 있다.

그럼에도 Spring Boot를 선택한 이유는 운영 안정성과 포트폴리오 관점이 컸다.

이 프로젝트는 외주 프로젝트이면서 동시에 내가 직접 기획, 개발, 배포, 운영까지 경험하는 프로젝트였다.
그래서 단순히 가장 빠른 길만 선택하기보다는, 실제 백엔드 구조를 분리해서 만들어보고 싶었다.

Spring Boot를 선택하면서 얻을 수 있는 장점은 다음과 같았다.

Controller, Service, Repository 구조를 명확하게 나눌 수 있음
DB 연동과 트랜잭션 처리가 안정적임
검증 로직과 예외 처리를 백엔드에서 관리하기 좋음
관리자 API와 사용자 API를 분리하기 좋음
포트폴리오에서 백엔드 경험을 설명하기 좋음

특히 후기 작성, 후기 삭제, 관리자 삭제, 통계 기록 같은 기능은 백엔드에서 책임지는 것이 맞다고 판단했다.
프론트엔드는 화면과 사용자 경험에 집중하고, 백엔드는 데이터 저장, 검증, 보안, 통계 처리를 담당하는 구조로 나누었다.

MySQL, PostgreSQL, Google Sheet를 고민했다

DB를 선택할 때는 세 가지를 고민했다.

첫 번째는 Google Sheet였다.

Google Sheet는 견적 옵션처럼 사람이 직접 수정해야 하는 데이터에는 잘 맞았다.
하지만 후기처럼 사용자가 계속 등록하는 데이터나 비밀번호 검증이 필요한 데이터에는 적합하지 않았다.

두 번째는 MySQL이었다.

MySQL은 가장 익숙하고 많이 쓰이는 관계형 데이터베이스라 충분히 좋은 선택지였다.
후기, 관리자, 통계 정도의 기능이라면 MySQL로도 전혀 문제없이 구현할 수 있다.

세 번째는 PostgreSQL이었다.

PostgreSQL은 MySQL과 마찬가지로 관계형 데이터베이스이지만, Supabase와 함께 사용하기 좋고, 실제 서비스에서도 많이 쓰이는 DB라 경험해보고 싶은 이유도 있었다. 외주 프로젝트에서 새로운 기술을 무리하게 쓰는 것은 조심해야 하지만, 이번 규모에서는 PostgreSQL을 적용해도 리스크가 크지 않다고 판단했다.

결과적으로 역할을 나누었다.

Google Sheet: 견적 옵션 관리
PostgreSQL: 후기, 관리자 통계, 사용자 이벤트 저장

Google Sheet를 완전히 버리지 않은 이유는 클라이언트 입장에서 견적 옵션 수정이 가장 쉬운 도구였기 때문이다.
반대로 후기와 통계는 정합성과 보안이 필요하므로 PostgreSQL에 저장하는 것이 더 적합했다.

이렇게 모든 데이터를 하나의 DB로 몰아넣기보다는, 데이터의 성격에 따라 저장 방식을 나누었다.

Supabase를 선택한 이유

PostgreSQL을 직접 서버에 설치해서 운영하는 방법도 있었지만, 이번 프로젝트에서는 Supabase를 사용했다.

가장 큰 이유는 비용과 관리 편의성이었다.

Supabase는 무료 플랜으로 시작할 수 있고, PostgreSQL 기반이라 백엔드에서 연결하기도 어렵지 않았다.
별도로 DB 서버를 설치하거나 관리하지 않아도 된다는 점도 좋았다.

외주 프로젝트에서 중요한 것은 “만든 뒤에도 관리 가능한 구조인가”라고 생각했다.

직접 DB 서버를 운영하면 자유도는 높지만, 백업, 보안, 접속 권한, 장애 대응 같은 관리 부담이 커진다.
반면 Supabase는 작은 규모의 서비스에서 시작하기에 부담이 적었다.

물론 무료 플랜에는 제한이 있다. 트래픽이 커지거나 데이터가 많아지면 유료 플랜이나 다른 인프라로 옮겨야 할 수 있다.

하지만 예상 유입량과 프로젝트 규모를 고려했을 때, 초기 운영에는 Supabase가 적절하다고 판단했다.

Render와 Vercel로 배포를 나눈 이유

프론트엔드는 Vercel에 배포했고, 백엔드는 Render에 배포했다.

Next.js와 Vercel은 궁합이 좋다. GitHub에 코드를 푸시하면 자동으로 빌드되고 배포되는 구조를 만들 수 있어서 운영이 편했다. 도메인 연결도 비교적 간단했다.

반면 Spring Boot 백엔드는 별도의 서버 환경이 필요했다. 그래서 Render를 사용했다.

처음에는 Render 무료 플랜으로 테스트했다.
하지만 무료 플랜은 일정 시간 요청이 없으면 서버가 잠들고, 다시 접속할 때 콜드 스타트가 발생한다.
실제로 견적 옵션이나 후기 로딩이 느리게 느껴질 수 있었다.

운영 사이트에서는 사용자가 견적 페이지에 들어갔을 때 오래 기다리면 이탈할 가능성이 있다.
그래서 최종적으로는 Starter 플랜을 고려하게 되었다.

정리하면 역할은 이렇게 나뉘었다.

Vercel: Next.js 프론트엔드 배포
Render: Spring Boot 백엔드 배포
Supabase: PostgreSQL DB 운영
Google Sheet: 견적 옵션 관리
Cloudflare/Gabia: 도메인 및 DNS 관리

비용과 유지보수 사이의 균형

외주 프로젝트에서는 무조건 기술적으로 좋은 구조가 정답은 아니라고 느꼈다.

좋은 구조를 만들수록 운영 비용이나 관리 포인트가 늘어날 수 있다.
반대로 비용을 너무 줄이면 기능 확장이나 보안, 안정성에서 문제가 생길 수 있다.

이번 프로젝트에서는 비용과 유지보수 사이에서 균형을 잡는 것이 중요했다.

예를 들어 견적 옵션은 DB 관리자 페이지를 따로 만들 수도 있었다.
하지만 클라이언트가 개발자가 아니고, 옵션 수정이 자주 필요할 수 있다는 점을 생각하면 Google Sheet가 더 현실적인 선택이었다.

반대로 후기는 Google Sheet에 저장할 수도 있었지만, 비밀번호 검증과 삭제, 관리자 기능까지 고려하면 DB에 저장하는 것이 더 안전했다.

즉, 모든 기능에 같은 기준을 적용하지 않고, 기능별로 가장 적합한 방식을 선택하려고 했다.

클라이언트가 직접 자주 수정해야 하는 데이터 -> Google Sheet
보안과 정합성이 필요한 데이터 -> PostgreSQL
화면과 사용자 경험 -> Next.js
검증과 저장 로직 -> Spring Boot

이런 식으로 역할을 나누니 구조가 훨씬 명확해졌다.

이번 기술 선택을 통해 배운 점

이번 프로젝트를 하면서 기술 스택 선택은 단순히 “내가 익숙한 기술”이나 “요즘 많이 쓰는 기술”로 정하면 안 된다는 것을 느꼈다.

특히 외주 프로젝트에서는 클라이언트가 앞으로 어떻게 관리할지, 운영 비용은 얼마나 감당할 수 있는지, 기능이 더 늘어날 가능성이 있는지까지 같이 봐야 했다.

처음에는 서버 없이 간단하게 끝낼 수 있을 것 같았지만, 후기와 관리자 기능이 추가되면서 백엔드가 필요해졌다.
그리고 백엔드가 생기면서 DB, 배포 서버, 환경변수, CORS, 보안 같은 운영 요소도 함께 고려해야 했다.

결국 기술 스택은 기능 목록만 보고 정하는 것이 아니라, 운영 방식까지 포함해서 결정해야 한다는 걸 배웠다.

회고

이번 기술 선택에서 가장 크게 느낀 점은 “작은 프로젝트도 운영을 생각하면 작지 않다”는 것이었다.

겉으로 보기에는 단순한 홈페이지였지만, 실제로는 견적 옵션 관리, 후기 작성, 관리자 페이지, 통계, 배포, 도메인, SEO까지 연결되어 있었다.

Next.js와 Spring Boot를 선택한 것은 단순히 기술을 많이 쓰기 위한 선택이 아니라, 프론트와 백엔드의 책임을 나누고 실제 운영 가능한 구조를 만들기 위한 선택이었다.

다음 프로젝트에서는 처음부터 기능별 데이터 성격을 더 빠르게 분류해보고 싶다.

“이 데이터는 누가 수정하는가?”, “보안이 필요한가?”, “나중에 관리자가 직접 다뤄야 하는가?” 같은 질문을 먼저 던지면 기술 선택도 훨씬 명확해질 것 같다.