💡 상황 해독
현재 상태: 튼튼하지만 묵직한 장고(Django)와 몽고DB 위에서 시스템을 직접 구축하며 버텨온 백엔드 장인이, 트렌디함과 속도를 무기로 하는 Next.js 진영에 막 발을 들인 상태입니다.
핵심 쟁점:
사고의 충돌: "무조건 서버에서 하던 일"을 "브라우저(Client)와 서버"로 나눠 생각해야 하는 뇌의 과부하.
환경의 파편화: API 서버(DRF)를 따로 만들지 않고 함수로 해결하는 방식에 대한 낯선 편리함.
인프라의 벽: "Nginx 상설 노가다"를 계속할 것인지, "오케스트레이션(Swarm/K8s)"으로 점프할 것인지의 기로.
예상 vs 현실:
상상: 장고처럼 파일 하나에 다 짜고 서버 한 대 띄우면 되겠지?
현실: 뭐만 하면 async를 붙여야 하고, 컨테이너를 5개씩 띄워도 메모리가 남는(40MB) 기현상을 목격하며 설계의 근예(MSA)를 강제로 고민하게 됨.
영향 범위: 이 고비를 넘기면 "혼자서 개발-배포-운영까지 다 하는 풀스택 아키텍트"가 되지만, 여기서 멈추면 "JS 문법 좀 아는 백엔드 개발자"에 머물게 됩니다.
🔍 원인 투시
근본 원인: 현대 웹은 "데이터의 무결성(장고 강점)" 못지않게 **"극강의 사용자 경험(Next.js 강점)"**을 요구합니다. 이 두 세계를 연결하는 '언어의 장벽(Python vs JS)'과 '인프라의 복잡도'가 모든 고민의 시작입니다.
인과 흐름: 사용자 요구 증가 → 프론트엔드 비중 커짐 → 기존 장고식 SSR만으로는 한계 → Next.js 도입 → 인프라 관리 포인트 증가 → 물량 공세(Scale-out) 필연성 발생.
현실 비유:
장고: 모든 재료를 한 솥에 넣고 끓이는 '대형 전골 요리'. 든든하지만 국물 하나 바꾸려면 솥을 다 비워야 함.
넥스트 & 스웜: 조리된 음식을 5명의 배달원이 각자 배달하는 '전문 배달 시스템'. 한 명 사고 나도 대장이 0.1초 만에 새 배달원을 투입함.
숨겨진 요인: 쿠버네티스의 '거대함'이 주는 공포가 오히려 가장 효율적인 대안인 '스웜'을 보지 못하게 가리고 있음.
🛠️ 해결 설계도
1단계: 서버와 클라이언트의 '영역 표시' (Next.js 로직 정복)
핵심 행동: "주방에서 할 일(Server)"과 "홀에서 할 일(Client)"을 정확히 분리하여 쪼개기.
실행 가이드: DB를 직접 만지는 모든 로직은
actions.ts
('use server')로 보내고, 버튼을 누르거나 입력하는 모양새는 components/('use client')에 가두기.
성공 지표: 브라우저 개발자 도구의 'Network' 탭에 DB 비번이나 로직이 노출되지 않는지 확인.
코드:
tsx
// Before: 모든 걸 한 페이지에 다 때려박기 (보안 위험, 에러 폭발)
export default function LegacyPage() {
const data = supabase.from('...').select(); // 클라이언트에서 DB 접근 시도 (No!)
return <button onClick={() => delete(data.id)}>삭제
}
// After: 주방(Actions)에 주문 넣기
// app/actions.ts
'use server'
export async function deleteItem(id: number) { return await supabase.from('...').delete().eq('id', id); }
// app/components/DeleteBtn.tsx
'use client'
import { deleteItem } from '@/app/actions';
export default function DeleteBtn({ id }) {
return <button onClick={() => deleteItem(id)}>삭제
}
팁: 'use client'를 "부끄러운 것"이라 생각하고 최소한으로 사용하세요. 적게 쓸수록 사이트가 빨라집니다.
2단계: 이미지 '박제' 및 시스템 자동화 (도커/스웜 배포)
핵심 행동:
docker-compose.yml
을 단순 실행기가 아닌 **'부대 지휘관 명령서'**로 업그레이드하기.
실행 가이드: deploy 문법을 추가하고, Docker Swarm을 통해 5명의 '복제 인간' 컨테이너가 서로를 감시하게 만들기.
성공 지표: 컨테이너 하나를 강제로 kill 했을 때, 1초 만에 새 컨테이너가 이름표 바꿔 달고 튀어나오는지 확인.
실수 방지: package-lock.json을 절대
.gitignore
하지 마세요. 도커라는 공장이 돌아가기 위한 부품 명세서입니다.
🧠 핵심 개념 해부
[BFF (Backend for Frontend): 안내데스크]
설명: 손님(브라우저)이 장고(큰 공장)를 직접 찾아가지 않게 입구에서 맞춤형으로 안내해주는 전문 직원.
실무 예시: 장고에서 주는 거대한 JSON 데이터를 Next.js가 예쁘게 다듬어서 화면에 딱 필요한 만큼만 보여주는 것.
중요성: 백엔드 로직이 더러워지는(?) 걸 막아주고 프론트엔드가 자유롭게 춤추게 해줌.
[Routing Mesh: 투명 로드밸런싱]
설명: 5개의 문 중 어느 문을 발로 차고 들어와도, 뒤쪽에서 안내원이 가장 한가한 방으로 슉 배달해주는 마법 통로.
중요성: 이제 Nginx 설정 파일 열어서 upstream 일일이 적으며 "씨부랄" 소리 낼 필요가 없음.
오해: "Nginx가 없어도 된다는 건가?" ➡️ 아니요, Nginx는 문지기만 하고 복잡한 길 찾기는 스웜이 다 한다는 뜻입니다.
[Server Actions: 직통 전화]
설명: 주소(URL)를 몰라도 번호 하나('함수 이름')만 알면 백엔드 주방장과 바로 통화하는 전용선.
중요성: DRF 시리얼라이저 짜고 URL 설계하는 시간의 80%를 아껴줌.
🔮 성장 전략 & 실전 지혜
예방·지속 전략:
DB 커넥션 풀이 터진다면 무조건 PgBouncer를 세우세요. 넥스트의 싱글스레드 한계를 인정하는 게 고수의 시작입니다.
코드를 고쳤는데 도커에 반영이 안 된다면? 배포 파일은 코드를 품고(Build) 있어야 한다는 원칙을 상기하세요.
라이트하우스(Lighthouse) 점수는 80점이면 충분합니다. 100점에 목매다 서비스를 못 내는 건 하수입니다.
전문가 마인드셋: 고수들은 **"인프라 관리에 드는 시간을 어떻게 0으로 수렴시킬까"**를 고민합니다. 그 답이 바로 Managed DB(Supabase)와 Docker Swarm입니다.
학습 로드맵:
1단계: Next.js App Router (현재 상태)
2단계: Prisma/Drizzle (순정 DB 주무르기)
3단계: GitHub Actions (자동 빌드/푸시)
4단계: Traefik (HTTPS까지 자동화하는 인프라 마법)
🌟 실전 적용 플랜
즉시 실행 액션:
.gitignore
에서 package-lock.json 삭제하기 (제일 시급).
docker service scale 명령어로 5개를 10개로 늘려보고 docker stats로 쾌감 느끼기.
actions.ts
에
delete
기능 하나 추가해보기.
중기 현장 프로젝트:
친구와 분업 시나리오 대로 "이미지 업로드 게시판" 1주일 안에 완성하기.
실제 VPS(오라클, AWS 등)에 Docker Swarm으로 2개 호스트 묶어보기.
숙련도 자가진단:
"Nginx upstream 설정 없이 분산 서비스 띄울 수 있어?" ➡️ "YES"가 나오면 합격.
"Next.js에서 API 주소 없이 데이터 처리할 수 있어?" ➡️ "Server Actions!"가 나오면 합격.
📝 핵심 메시지 압축 요약
넥스트JS는 단순히 "프론트엔드 도구"가 아니라, 당신의 인프라 철학을 바꾸는 문입니다. 40MB의 가벼운 컨테이너 수십 개를 조종하는 도커 스웜의 대장이 되어, 장고의 안정감과 넥스트의 민첩성을 모두 챙기세요. 이제 Nginx 설정 파일 대신 비즈니스 로직을 고민하는 '영리한 시스템 아키텍트'로 성장할 시간입니다. ㅅㄱ!!! 🚀🐳🔥
nextjs는 다필요없고 엄청편리한 개복치라는 느낌이다. 내가 개발을 시작한지 얼마 돼지 않아 많은 웹앱을사용하지 않아서 자연스레 장고랑 비교하게 되었다.
일단 본연의 성능을 유지하기위해 기능적인건 ssr은 최소화하는게 좋을거같다. 싱글스레드인게 크기도하고 그래서 비동기 떡칠해놓은것도 있고, 아마 헤비한 로직은별도의 fast api같은걸로 처리해서 전달받거나 해야할거고, 그러니까 편리하고 경량화된 중간자의 역할같은 느낌.
진짜 딱 웹서버의 본연의 역할(내가생각하는)에 충실하다. 대신 ai랑 대화하다보면서 느낀건 컨테이너 오케스트레이션은 피해갈수없는 운명인듯하다.
현재 사이트의 경우 각종 기능과 js css 등을 떡칠해놓고 난독화까지 걸어놓은상태. 장고는 워커가 여러개라 나름 나쁘지 않게 사용가능하지만 아마 넥스트는 자가의 힘보다는 외부의존으로 돌리는 전략이 필요할듯하다. 그리고 간단한 페이지지만 도커라이즈로 띄워보니 램이 40mb인게 충격이였다.
40mb를보고 아 컨테이너를 걍 여러대 띄우라고 만든거구나 싶었다. 이게 현대아키텍처구나 싶더라. 결국 매우편하고 ㅈ간지나고 유행인대신에, 곁다리로 배워야할게 존x많네? 근데 나는 프엔빼고 js빼고 ts뺴고 음...다 알겠군(그냥 다모르는거 맞다)싶더라 음음 알아보니 벌셀인가 vercel인가도 트래픽에따라 자동으로 컨테이너 늘려준다는 기능이 있다니 cicd만 있는줄알앗는데말야. 결국 나같은 셀프호스트는 꼬우면 직접해야한다. 그래서 꼬와서 바로 도커스웜으로다가 롤링업데이트 테스트도 해봤다. 꼬와서 덕분에 도커 스웜도 해보고 좋네. 매우 편리하더라. nginx에서 포트지정하고 upsteam으로 일일히 묶어줄필요가 없어서 좋은듯하다.
db는...ㅡㅡ 일단 수파쓰는데 아마 돈내기싫어서 그냥 순정pg에 커넥션풀 관리하는얘 뭐더라? 걔쓸거같긴하다. db연결도 개쉽고 빠르더라. crud 구현 10분만에끝난듯. 아직 들 꼽더라. 근데 꼬울예정.
요약: next 개복치임-> 그래서 물량으로 때워야함 -> 그래서 오케스트레이션 해야함 -> 그래서 롤링업데이트 시나리오테스트겸 처음으로 도커스웜써봤는데 엄청좋고 편리하더라 -> 백단도 별도 api 서버 구현하는게 좋을수도 -> 진입은 쉽지만 결국 msa를 상당히 알아야 제대로 써먹을듯? 아님말고!
이상 공식개발 0년차 개발자나부랭이가 나중에 기억할라고 써봄 ㅅㄱ