가이드

Supabase Edge Function 배포하기: 200 떠도 안심 금지

읽는 데 약 7분#Supabase#가이드#배포

한줄 요약: Edge Function을 배포하는 길은 대시보드와 CLI 두 가지입니다. 이 글은 둘 중 무엇을 고를지 기준을 주고, 배포 후 무엇이 생기는지, 그리고 HTTP 200이 떠도 그게 완료라는 뜻은 아니라는 것을 실제 배포 기록으로 보여줍니다. 코드를 고치면 반드시 다시 배포해야 반영된다는 것도 함께 다룹니다.

Edge Function이 뭔가

Edge Function은 내 서버 없이 코드 한 조각을 인터넷에 띄워 두고, 주소로 불러서 실행시키는 것입니다. AI가 짜 준 코드 중에 “리뷰를 긁어와 표로 정리한다”, “부정적인 반응이 오면 알린다” 같은 부분은 내 컴퓨터를 계속 켜 두지 않아도 돌아가야 합니다. Edge Function이 그 역할을 맡습니다. 배포하고 나면 주소(엔드포인트)가 하나 생기고, 그 주소를 부르면 코드가 실행됩니다.

앞선 가이드 글에서 다룬 구분을 그대로 쓰면 언제 필요한지가 쉽게 갈립니다. 브라우저에서 도는 코드(사용자가 화면을 열어야 실행되는 코드)와 서버에서 도는 코드(사용자가 접속하지 않아도 저 혼자 돌아야 하는 코드)입니다. Edge Function은 후자를 위한 자리입니다.

리뷰를 긁어와 저장하는 작업이나 부정적인 반응이 오면 알리는 작업은 사용자가 화면을 보고 있을 때만 도는 게 아니라, 정해진 시각이나 이벤트에 맞춰 저 혼자 돌아야 합니다. 브라우저 코드는 화면을 닫으면 같이 멈추기 때문에 이런 일은 못 맡습니다. 반대로 로그인한 사용자가 자기 글 목록을 보는 것처럼 화면을 열어야만 필요한 일은 굳이 Edge Function으로 옮기지 않아도 됩니다. RLS를 켠 공개용 키로 브라우저에서 바로 불러도 충분합니다. 만능 키(secret, service_role)를 써야 하는 작업이라면 그 코드는 브라우저가 아니라 서버 쪽, 즉 Edge Function 같은 자리에 있어야 합니다.

두 경로 중 뭘 고르나

Supabase에서 Edge Function을 올리는 길은 두 가지입니다. 대시보드에서 만드는 길CLI(명령 줄 도구, 마우스 대신 글자로 된 명령을 쳐서 실행하는 방식)로 올리는 길입니다. 둘 다 결과물은 같은 Edge Function이지만, 가는 방법과 어울리는 상황이 다릅니다. 이 글은 이어지는 절 전부를 대시보드 경로 기준으로 다룹니다. CLI는 아래에서 무엇이 다른지, 언제 어울리는지까지만 짚습니다.

대시보드에서 만들기

  1. 준비물 브라우저만 설치할 것이 없습니다
  2. 코드를 어디에 두나 화면 안 에디터 붙여넣고 Deploy 버튼
  3. 맞는 상황 함수 하나, 빠르게 테스트 처음 배포해 보는 경우

빠르지만 함수가 늘어나면 화면을 오가며 관리해야 합니다

CLI로 올리기

  1. 준비물 CLI 설치, 로컬 개발 환경 터미널을 쓸 줄 알아야 합니다
  2. 코드를 어디에 두나 내 컴퓨터의 파일 깃(Git) 버전관리와 잘 맞습니다
  3. 맞는 상황 함수 여러 개, 반복 배포 코드를 로컬에서 계속 고치는 경우

준비가 더 필요하지만 함수가 늘어날수록 편해집니다

이 글처럼 함수가 두 개(collect-reviews, notify-negative)뿐이고 처음 배포해 본다면 대시보드 쪽이 더 맞습니다

대시보드에서 실제로 누르는 순서

대시보드 쪽을 골랐다면 뒤에서 나올 목록 화면(functions-list.webp)의 Deploy a new function 초록 버튼부터 시작합니다. 그 버튼을 누른 뒤 절차는 Supabase 공식 문서의 Dashboard Quickstart 기준으로 이렇습니다.

  1. Edge Functions 목록 화면에서 Deploy a new function을 누릅니다.
  2. Via Editor를 고릅니다. 파일을 올리는 방법도 있지만 처음이면 이쪽이 간단합니다.
  3. 준비된 템플릿(예: Hello World)을 고르거나, 빈 화면에서 바로 시작합니다.
  4. 화면 안 코드 편집기에 템플릿 코드가 뜹니다. 여기서 내용을 지우고 붙여넣거나 고칩니다.
  5. 편집기 아래 Deploy function 버튼을 누릅니다.
  6. 10초에서 30초 정도 기다리면 배포가 끝났다는 메시지가 뜹니다.

터미널도, 설치도 필요 없습니다. 코드를 화면 안 에디터에 두고 버튼으로 올리는 것이 대시보드 경로의 전부입니다.

배포하면 뭐가 생기는가

배포가 끝나면 Edge Functions 목록에 함수 이름과 주소(엔드포인트)가 한 줄로 생깁니다.

Supabase 대시보드 Edge Functions 목록 화면. Run server-side logic close to your users라는 부제와 Deploy a new function 초록 버튼이 있고, 표에 NAME과 URL과 UPDATED 열 아래 collect-reviews와 notify-negative 두 함수가 올라와 있다
배포된 함수 두 개(collect-reviews, notify-negative). 프로젝트 주소 일부는 캡처에서 블러 처리했습니다

함수 이름을 누르면 상세 화면으로 들어갑니다. 여기서부터가 배포 이후에만 생기는 것들입니다.

collect-reviews 함수 상세 화면 상단. 함수 이름 아래 엔드포인트 주소가 있고 Overview, Invocations, Logs, Code, Settings 탭이 나열돼 있으며 오른쪽에 Docs, Download, Test 버튼이 있다
함수 상세 화면. 엔드포인트 주소와 함께 Invocations(호출 기록), Logs(실행 로그) 탭이 붙습니다. 프로젝트 주소 일부는 캡처에서 블러 처리했습니다

호출해서 확인하기

배포된 함수는 오른쪽 위 Test 버튼으로 화면 안에서 불러볼 수도 있고, 같은 화면의 “Invoke function” 상자에 있는 코드를 복사해 터미널에서 불러볼 수도 있습니다. 탭은 cURL, JavaScript, Swift, Flutter, Python 다섯 개가 있고 기본은 cURL입니다.

함수 상세 화면의 Invoke function 코드 상자. cURL, JavaScript, Swift, Flutter, Python 탭이 있고 cURL 내용은 curl -L -X POST 뒤에 함수 주소, Authorization Bearer와 apikey 헤더에 SUPABASE_PUBLISHABLE_KEY, Content-Type 헤더, 마지막에 name Functions를 담은 데이터가 이어진다
cURL로 부르는 예시 코드. 주소 일부는 캡처에서 블러 처리했습니다

두 헤더(Authorization, apikey) 자리에는 anon 또는 publishable 키를 넣습니다. 이 키가 무엇이고 어디서 찾는지는 앞선 가이드 글에서 다룹니다.

안 되면 어디를 보나

배포는 됐는데 호출이 안 되거나, 호출은 되는데 결과가 이상할 때가 있습니다. 함수 상세 화면의 탭 다섯 개(Overview, Invocations, Logs, Code, Settings) 중 이럴 때 볼 곳은 두 개, InvocationsLogs입니다. 성격이 다릅니다.

뭘 보여주나
Invocations 요청과 응답 기록: 헤더, 본문, 상태 코드, 걸린 시간
Logs 함수 코드 안에서 무슨 일이 있었는지: console.log 출력, 잡히지 않은 예외와 스택 트레이스

호출 자체가 401로 막힌다면 대개 헤더에 넣은 키가 비었거나 틀린 경우입니다. 위에서 본 Authorization, apikey 두 헤더에 어떤 키를 넣어야 하는지는 앞선 가이드 글에서 다룹니다.

호출은 200으로 끝났는데 결과가 이상하다면 호출 방식이 아니라 코드 안의 문제입니다. 이때는 Logs 탭을 봅니다. 함수 코드에 console.log를 넣어 두면 그 출력이 여기 쌓이고, 코드가 도중에 잡히지 않은 예외를 던지면 에러 메시지와 스택 트레이스가 여기 남습니다. 다만 아래에서 볼 fetched: 3 사례처럼 코드가 죽지 않고 끝까지 실행되면서 숫자만 조용히 작게 나오는 경우는 예외도 에러 메시지도 없어서 Logs 탭만으로는 원인을 못 찾습니다. 그럴 때는 다음 절처럼 응답 본문의 숫자를 내가 아는 값과 대조하는 수밖에 없습니다.

고쳤는데 반영이 안 된다면 재배포를 안 한 경우입니다. 이 글 마지막 절에서 다룹니다.

HTTP 200이 나와도 완료가 아닙니다

여기가 이 글의 핵심입니다. 불러봤더니 HTTP 200이 떴다고 해서 끝난 게 아닙니다.

리뷰 페이지를 긁어와 표로 정리하는 함수(collect-reviews)를 배포하고 실제로 불러본 과정에서 이런 일이 있었습니다.

배포 응답 본문
1차 배포 fetched 3건
재배포 (페이지 루프 추가) HTTP 200, 5.3초, {"fetched":29,"negative":4,"inserted":26}

1차 배포에서도 함수는 끝까지 실행돼 fetched: 3이라는 응답을 돌려줬습니다. 그런데 실제로 받아와야 할 리뷰는 그보다 훨씬 많았습니다. 원인은 함수 코드가 리뷰 목록의 첫 페이지만 읽고, 페이지네이션(여러 쪽으로 나뉜 목록을 한 쪽씩 넘겨 가며 받는 것) 없이 다음 페이지로 넘어가지 않아서였습니다. 알라딘 리뷰는 여러 페이지에 나뉘어 있는데, 첫 페이지만 읽으면 전체의 극히 일부만 가져오게 됩니다.

이 페이지네이션 문제는 사실 이번이 처음도 아니었습니다.

이 3건이 이상하다는 것을 어떻게 알았느냐면, 로컬에서 따로 센 리뷰 건수(14건)와 응답의 fetched 값(3건)이 맞지 않았기 때문입니다. 그 차이를 파고들어 페이지네이션이 빠져 있다는 것을 찾았습니다.

문제를 고친 뒤에는 코드에 페이지를 넘기며 읽는 부분을 추가하고 다시 배포했습니다. 그 결과가 위 표의 두 번째 줄, fetched: 29입니다.

같은 함수를 다시 부르면 어떻게 될지도 확인이 필요한 부분입니다. collect-reviews는 테이블에 review_hash라는 값에 유일함(unique) 제약을 걸어 두어서, 같은 함수를 여러 번 불러도 이미 저장된 리뷰가 중복으로 쌓이지 않습니다. 실제로 재실행해서 inserted 값이 줄어드는 것으로 확인했습니다.

고치면 반드시 다시 배포해야 합니다

로컬에서 코드를 고쳐도 이미 배포된 함수는 그대로입니다. 다시 배포해야만 고친 내용이 반영됩니다. 위 사례에서도 페이지네이션 코드를 추가한 다음 재배포를 하지 않았다면 여전히 3건짜리 함수가 돌고 있었을 것입니다.

이 글의 화면과 절차는 2026년 8월 24일에 Supabase 공식 문서의 배포 안내, Dashboard Quickstart, Logs 안내, 트러블슈팅 안내로 확인했습니다. Supabase는 대시보드 구성과 CLI 문법을 바꾼 적이 있습니다. 배포 명령의 정확한 문법과 최신 화면은 위 문서에서 그때그때 확인하세요.

댓글

    핀번호는 내 댓글을 지울 때 필요합니다.

    뉴스레터

    새 글을 메일로 받아보세요

    AI 자동화 튜토리얼과 저자 코멘터리를 보냅니다. 스팸 없이, 새 글이 올라올 때만.

    구독하기 ›