블로그를 서브도메인에서 하위 경로로 옮긴 이유, 그리고 CSP가 애드센스를 막고 있었습니다
회사 사이트와 기술 블로그를 따로 운영하는 구성은 흔합니다. 회사는 duolabs.co.kr, 블로그는 blog.duolabs.co.kr.
회사 사이트와 기술 블로그를 따로 운영하는 구성은 흔합니다. 회사는 duolabs.co.kr, 블로그는 blog.duolabs.co.kr.
Next.js와 PostgreSQL로 만든 웹 애플리케이션을 운영할 때 관리형 플랫폼과 VPS 중 어느 쪽이 더 저렴한지는 월 기본요금만으로 판단하기 어렵습니다. 관리형 플랫폼은 배포와 확장을 대신 처리하고, VPS는 낮은 인프라 비용 대신 서버 운영을 직접 맡아야 합니다.
웹사이트를 운영하다 보면 루트 주소에서 robots.txt라는 작은 텍스트 파일을 만나게 됩니다. 내용은 몇 줄뿐인데 검색엔진 최적화 점검표에는 거의 빠지지 않고 등장합니다.
호스팅 서비스를 비교할 때 가장 먼저 확인해야 할 것은 가격표가 아니라 서로 같은 종류의 서비스를 비교하고 있는가입니다. AWS와 Vercel, Railway와 VPS는 모두 애플리케이션을 운영할 수 있지만 사용자가 직접 관리해야 하는 범위가 다릅니다.
문서 질의응답 기능은 검색과 답변 생성을 함께 수행하기 때문에 일반 API보다 처리 비용이 큽니다. 그런데 모바일 화면에서 제공하는 질문이 미리 준비된 여덟 개로 고정되어 있다면 캐시 대상은 매우 작아집니다.
문서 AI 기능을 로컬에서 완성하고 운영에 배포했을 때, 답변 자체는 정상인데 화면의 느낌이 완전히 달라졌습니다. 스트리밍 답변은 한꺼번에 나타났고, 전체 화면 패널은 작은 섹션 안에 갇혔으며, 모달이 열리자마자 배경 스크롤 잠금이 풀렸습니다.
챗봇 답변을 한 글자씩 흘려보내는 것은 기술적 과시가 아닙니다. 사람이 기다릴 수 있게 만드는 장치입니다. 같은 5초라도 빈 화면을 보는 5초와 글자가 차오르는 5초는 완전히 다른 시간입니다.
무료 티어에서 걸린 문제들을 Pro 요금제로 올리면 몇 개가 사라질까. 세어보니 용량 문제는 전부 지워졌는데 블로커는 오히려 하나 늘었다. 돈으로 사는 것과 못 사는 것의 경계에 대한 기록.
잘 돌아가던 개인 프로젝트를 Vercel과 Supabase 무료 티어로 옮길 수 있을지 검토했다. 요금제 한도표부터 보는 대신 코드를 먼저 읽었고, 진짜 제약은 숫자가 아니라 실행 모델 쪽에 있었다.
Vercel 같은 서버리스 환경에 백그라운드 작업 큐와 요청 제한을 붙이려고 문서를 펼치면
Next.js로 웹 서비스를 만들 때 AWS 서비스를 하나씩 고르면 꽤 긴 목록이 나온다. CDN, API 입구, 함수 실행, PostgreSQL, 인증, 파일 저장, Redis, Queue, 이벤트 예약, 배포 파이프라인이 각각 다른 서비스다.
서버리스 프로젝트에 Worker를 붙일 때 QStash가 반드시 필요한 것은 아니다. 이미 Supabase를 사용하고 있다면 PostgreSQL 기반의 Supabase Queues로 작업을 저장하고, Vercel 함수가 메시지를 가져가 처리하는 구조를 만들 수 있다.
Vercel은 코드를 실행하고, Supabase는 데이터를 영구 저장하며, QStash는 비동기 작업을 전달한다. 여기까지 이해하고 나면 Redis의 자리가 모호하게 느껴질 수 있다.
서버리스 프로젝트에 비동기 처리를 추가하려고 하면 서비스 구성이 갑자기 복잡해 보인다. Vercel, Supabase, Upstash까지 연결했는데 Worker라는 이름이 하나 더 등장하기 때문이다.
Supabase를 처음 접하면 관리형 PostgreSQL 서비스로 이해하기 쉽습니다. 실제로 PostgreSQL은 Supabase의 중심이지만, 전체 제품은 데이터베이스보다 훨씬 넓은 범위를 다룹니다.
Vercel에 앱을 올리고, Supabase에 데이터를 저장하고, Upstash Redis로 요청 제한을 걸고, QStash로 비동기 작업을 전달한다고 해보자. 서비스 이름만 네 개다. 이쯤 되면 자연스럽게 이런 생각이 든다.
서버리스 서비스를 구성하다 보면 Supabase, QStash, Redis가 한 화면에 함께 등장합니다. 모두 데이터를 다루는 것처럼 보여 처음에는 무엇을 어디에 써야 하는지 헷갈리기 쉽습니다.
온프레미스에서 서비스를 운영하면 애플리케이션, 데이터베이스, Redis, WebSocket 서버와 백그라운드 워커를 한 네트워크 안에 둘 수 있습니다. 프로세스를 계속 띄워두기도 쉽습니다. setInterval로 10초마다 데이터베이스를 확인하는 코드도 일단은 잘 동작합니다.
웹사이트를 만들 때 자주 듣는 이름으로 Vercel, Cloudflare Pages, Netlify가 있습니다. 여기에 AWS나 직접 관리하는 서버까지 더하면 선택지가 너무 많아 보입니다. 하지만 먼저 구분할 것이 있습니다. 이들은 완성된 홈페이지를 만들어 주는 서비스가 아니라, 개발자가 작성한 코드를 빌드하고 실행하는…
GitHub에 커밋을 푸시하면 자동으로 서비스가 배포됩니다. 겉으로 보면 GitHub Actions의 Self-hosted Runner와 Vercel은 똑같아 보입니다.
웹사이트는 화면과 기능이 완성됐다고 바로 공개할 수 있는 상태가 되는 것은 아닙니다. 실제 사용자가 느끼는 속도, HTTP 보안 헤더, HTTPS 설정, 키보드 접근성, 구조화 데이터, DNS 설정은 서로 다른 문제입니다.
한국 사용자를 대상으로 운영 중인 데모 사이트에서 응답 지연을 점검했습니다. 도메인은 Cloudflare 프록시를 거치게 해뒀고, 원본 IP와 오리진을 보호하기 위해 켜둔 상태였습니다. 그러다 사이트를 손보는 중에 "버튼이 한 박자 늦게 눌리는 것 같다"는 얘기가 나왔고, 확인해 보니 앱 코드가 아니라 이 프록시 경로가…
사내 시스템은 외부 고객 서비스보다 사용자가 적다는 이유로 공개 전 점검이 짧아지기 쉽다. 하지만 결재, 계약, 인사, 회계처럼 업무의 기준이 되는 시스템은 한 번의 권한 오류나 데이터 손실도 실제 업무 중단으로 이어진다.
사내 시스템의 좋은 아키텍처는 가장 큰 서버나 가장 복잡한 기술 조합이 아니다. 현재 업무를 무리 없이 지원하고, 문제가 생겼을 때 되돌릴 수 있으며, 사용자가 늘면 필요한 부분만 확장할 수 있는 구조다.
월 10달러 안팎의 VPS를 보면 Vercel, Supabase 같은 관리형 서비스를 합친 것보다 훨씬 저렴해 보인다. 실제로 안정적인 부하가 있고 서버를 운영할 사람이 있다면 VPS가 경제적일 수 있다. 하지만 인스턴스 가격만 비교하면 백업, 저장 공간, 전송량, 보안 패치, 장애 대응 시간이 빠진다.
클라우드 비용은 서버 한 대의 월정액처럼 움직이지 않는다. 트래픽, 함수 실행 시간, DB 용량, 로그, 파일 전송, 실시간 연결이 각각 늘어난다. 작은 코드 실수나 공개된 API 키 하나가 짧은 시간에 사용량을 키울 수도 있다.
빠른 롤백은 사람이 명령어를 빨리 입력하는 능력이 아니다. 이전 버전이 무엇인지 알고, 같은 산출물을 다시 실행할 수 있고, DB가 이전 코드와 호환되도록 미리 설계한 결과다. 준비 없이 배포한 뒤 5분 안에 되돌리겠다는 목표는 지키기 어렵다.
브라우저가 파일을 애플리케이션 서버에 보내고, 서버가 다시 객체 저장소로 전달하는 방식은 이해하기 쉽다. 하지만 파일이 커지면 서버는 같은 데이터를 두 번 전송하고, 메모리와 실행 시간을 오래 점유한다. 서버리스 환경의 본문 크기 제한에도 걸리기 쉽다.
보고서 생성, 대량 메일, 이미지 변환, 외부 API 수집을 일반 API 요청 안에서 끝내려 하면 처음에는 단순해 보인다. 하지만 실행 시간이 길어질수록 브라우저, 프록시, 서버리스 함수 중 하나가 먼저 연결을 끊을 가능성이 커진다. 사용자가 다시 누르면 같은 작업이 중복 실행되기도 한다.
실시간 기능이 필요하다는 말은 요구사항이 아니다. 사용자가 몇 초 늦게 봐도 되는지, 서버에서 브라우저로만 보내면 되는지, 양쪽이 계속 메시지를 주고받아야 하는지부터 정해야 한다. 이 질문에 답하면 Polling, SSE, WebSocket, Supabase Realtime 중 선택이 쉬워진다.
모든 장애를 미리 예측할 수는 없다. 대신 사용자가 먼저 알려 주기 전에 이상을 발견하고, 원인을 좁힐 자료를 남기고, 같은 장애가 반복되지 않게 만들 수는 있다. 소규모 서비스의 모니터링은 비싼 도구보다 적은 수의 정확한 신호에서 시작하는 편이 낫다.
백업이 성공했다는 알림은 데이터를 되살릴 수 있다는 보증이 아니다. 파일이 손상됐거나, 필요한 암호화 키가 없거나, 복구 순서를 아무도 모르면 백업은 있어도 업무를 재개할 수 없다. 사내 시스템의 백업 설계는 저장 횟수보다 복구 목표와 복원 시험에서 시작해야 한다.
VPS를 만들면 몇 분 안에 공인 IP가 생기고 인터넷에서 접속할 수 있다. 편리하지만 그 순간부터 자동 스캔과 로그인 시도의 대상이 된다. 애플리케이션을 올리기 전에 운영체제와 접속 경로부터 잠그는 이유다.
사내 시스템은 직원 수가 적다고 해서 항상 가볍지 않다. 20명이 쓰는 문서 변환 시스템은 100명이 쓰는 단순 결재 시스템보다 더 많은 CPU와 저장 공간을 요구할 수 있다. 그래서 배포 구조는 인원수보다 동시 접속, 요청 시간, 파일 크기, 실시간 연결 수, 장애 허용 시간을 기준으로 정해야 한다.
앞선 글에서 백그라운드 작업을 분리하는 코드를 만들었습니다.
사내 시스템을 처음 만들 때는 Vercel, Supabase 같은 관리형 서비스를 조합하는 것이 효율적이다. 서버를 직접 관리하지 않아도 되고 사용자가 적은 시기에는 비용도 낮다.
온프레미스 Docker로 만든 쇼핑몰을 Vercel + Supabase로 옮긴 뒤,
웹 서비스에는 첨부 파일, 프로필 이미지, 업무 문서, 내보내기 파일과 백업 데이터를 저장할 공간이 필요하다. 대표적인 선택지는 Amazon S3와 Cloudflare R2다. 두 서비스 모두 안정적인 객체 스토리지지만 비용 구조와 강점은 꽤 다르다.
Next.js 서비스의 웹 화면과 API는 Vercel에 올릴 수 있지만, 모든 프로세스를 같은 방식으로 배포할 수 있는 것은 아닙니다. WebSocket 연결을 오래 유지하는 실시간 서버와 큐를 계속 확인하는 백그라운드 워커는 일반적인 웹 요청과 실행 방식이 다릅니다.
웹과 모바일 앱을 함께 제공하는 서비스를 배포할 때는 화면을 올리는 비용만 계산해서는 안 됩니다. 데이터베이스, 캐시, 실시간 통신, 백그라운드 작업, 이미지 저장소까지 포함해야 실제 운영비에 가까워집니다.
사내 시스템을 만들 때 가장 자주 나오는 질문 중 하나는 "직원 수가 늘어나면 서버 비용도 같은 비율로 늘어나는가"입니다. Vercel과 Supabase 조합에서는 직원 수보다 배포를 관리하는 개발자 수, 동시에 발생하는 요청, 데이터베이스 쿼리와 배치 작업이 비용에 더 큰 영향을 줍니다.
Vercel 배포는 성공했습니다. 프로젝트명.vercel.app 으로 접속하면 잘 뜹니다.
온프레미스로 돌아가던 서비스를 Vercel + Supabase로 옮겨보는 중이었습니다.
온프레미스 Docker로 돌아가던 서비스를 Vercel + Supabase로 옮기는 중이었습니다.
Docker 빌드가 느리면 패키지 설치나 애플리케이션 컴파일부터 보게 됩니다. 저도 타입 검사 실패를 고치는 데 집중하다가 그보다 앞선 load build context 단계에서 40초가 넘게 쓰이고 있다는 사실을 뒤늦게 봤습니다. 실패 원인과는 별개였지만, 매 배포마다 반복되는 낭비였습니다.
Next.js 앱에서 로컬 타입 검사는 통과하는데 Docker 배포에서만 같은 오류가 다시 나오면 코드보다 빌드 이미지에 무엇이 들어갔는지 봐야 합니다. 이번 작업에서는 린트, 타입 검사, 프로덕션 빌드를 모두 통과시킨 뒤 배포했는데 원격 빌드만 실패했습니다. 같은 커밋과 같은 잠금 파일을 썼으니 처음에는 환경 차이가 …
웹사이트는 공개 버튼을 누르는 순간 완성되는 것이 아니라 운영이 시작된다. 담당자, 지표, 콘텐츠 갱신, 보안 업데이트, 백업과 복구 절차가 없으면 잘 만든 사이트도 빠르게 낡는다. 이 글에서는 소규모 팀도 지속할 수 있는 웹사이트 운영 체계를 만드는 방법을 다룬다.
웹사이트를 만들었다고 네이버 검색 결과에 바로 나타나는 것은 아닙니다. 검색로봇이 사이트를 발견하고, 문서를 수집하고, 색인할 수 있어야 합니다. 네이버 서치어드바이저는 이 과정을 직접 보장하는 등록 창구라기보다 사이트 소유권을 확인하고 수집·색인 상태를 점검하는 운영 도구에 가깝습니다.
새 서브도메인을 추가한 직후 “Safari에서는 열리는데 Chrome에서는 안 열린다” 같은 일이 생길 수 있습니다. 이럴 때 바로 서버 장애나 DNS 설정 오류라고 판단하기 쉽지만, 실제 원인은 로컬 또는 브라우저 DNS 캐시인 경우가 많습니다.
Cloudflare Tunnel로 서비스를 노출하면 origin 서버가 보는 접속 IP가 실제 방문자 IP가 아닐 수 있습니다. 모든 요청이 터널 또는 프록시에서 온 것처럼 보이면 rate limit, 방문 통계, IP 차단 같은 기능이 부정확해집니다.
HSTS(HTTP Strict Transport Security)는 브라우저에 “이 도메인은 항상 HTTPS로만 접속해야 한다”고 알려주는 보안 정책입니다. 잘 설정하면 중간자 공격과 SSL stripping을 줄일 수 있지만, 성급하게 적용하면 장애 복구가 어려워질 수 있습니다.
웹사이트 주소 앞에 자물쇠 표시가 붙고 https://로 시작한다면 SSL/TLS 인증서가 사용되고 있다는 뜻입니다. 인증서는 방문자가 접속한 사이트가 진짜인지 확인하고, 주고받는 데이터를 암호화하는 역할을 합니다.