화. 8월 12th, 2025

G: 안녕하세요, 개발자 여러분! 오늘은 오픈 소스 백엔드의 강자, Supabase를 직접 서버에 설치하고 운영하는 방법에 대해 자세히 알아보겠습니다. Firebase의 강력한 대안으로 떠오른 Supabase를 직접 호스팅하면 비용 절감, 데이터 주권 확보, 그리고 더 깊은 커스터마이징의 자유를 누릴 수 있습니다. 이 가이드에서는 Docker를 이용하여 Supabase를 설치하고, 실제 서비스에 필요한 API 도메인까지 설정하는 과정을 단계별로 상세하게 알려드릴게요!


💡 왜 Supabase를 셀프 호스팅해야 할까요?

Supabase는 PostgreSQL 데이터베이스를 기반으로 인증(Auth), 스토리지(Storage), 실시간(Realtime), 엣지 함수(Edge Functions) 등 다양한 백엔드 기능을 제공합니다. 기본적으로 클라우드 관리형 서비스를 제공하지만, 다음과 같은 이유로 셀프 호스팅을 고려할 수 있습니다.

  • 비용 절감: 소규모 프로젝트나 트래픽이 예측 가능한 경우, 직접 서버를 운영하는 것이 장기적으로 더 저렴할 수 있습니다. 💰
  • 데이터 주권 및 보안: 민감한 데이터를 외부 클라우드에 두는 것을 원치 않거나 특정 규제 준수가 필요한 경우, 데이터를 직접 통제할 수 있습니다. 🔒
  • 최대 커스터마이징: Supabase의 내부 설정이나 컴포넌트를 깊이 있게 수정해야 할 필요가 있을 때 유용합니다.
  • 성능 최적화: 특정 지역에 서버를 배치하여 사용자에게 더 낮은 레이턴시를 제공하거나, 자체 인프라에 맞게 성능을 튜닝할 수 있습니다. ⚡

🛠️ 시작하기 전 준비물

Supabase 셀프 호스팅을 위해 다음과 같은 준비물이 필요합니다.

  1. 리눅스 서버 (VPS 또는 물리 서버):
    • Ubuntu 20.04+ 또는 CentOS 7+ (Ubuntu 권장)
    • 최소 2GB RAM, 2코어 CPU (PostgreSQL, Docker 등 여러 서비스가 실행되므로 최소 사양입니다. 실제 운영 시에는 더 높은 사양을 권장합니다.)
    • 여유 있는 디스크 공간 (데이터 저장용)
    • SSH 접속이 가능한 환경
  2. 도메인 이름: API 엔드포인트에 사용할 도메인 이름 (예: api.yourdomain.com, auth.yourdomain.com 등) 🌐
  3. 기본 리눅스 및 Docker 지식: 명령어 입력 및 파일 편집에 익숙해야 합니다.
  4. Git: Supabase 소스 코드를 클론하는 데 필요합니다.

📝 1단계: 서버 환경 설정 (Docker & Git 설치)

가장 먼저 Supabase를 실행할 서버에 Docker와 Git을 설치해야 합니다.

1.1 서버 업데이트

sudo apt update && sudo apt upgrade -y

1.2 Docker 설치

Docker 공식 스크립트를 사용하여 설치하는 것이 가장 안정적입니다.

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

설치 후 현재 사용자에게 Docker 그룹 권한을 부여하여 sudo 없이 Docker 명령어를 사용할 수 있게 합니다. (선택 사항이지만 편리합니다.)

sudo usermod -aG docker $USER
newgrp docker # 새 그룹 적용 (재로그인 필요)

1.3 Docker Compose 설치 (v2)

Docker Compose는 여러 Docker 컨테이너를 함께 정의하고 실행할 수 있게 해주는 도구입니다. Docker Desktop에 내장되어 있거나, 리눅스에서는 별도로 설치해야 합니다. 최근 버전의 Docker는 docker compose (하이픈 없음) 명령어를 사용합니다.

sudo apt install docker-compose-plugin

설치 확인:

docker --version
docker compose version

1.4 Git 설치

Supabase의 소스 코드를 가져오기 위해 Git이 필요합니다.

sudo apt install git -y

⚙️ 2단계: Supabase 프로젝트 설정

이제 Supabase의 소스 코드를 가져와 환경을 설정할 차례입니다.

2.1 Supabase 저장소 클론

원하는 디렉토리로 이동하여 Supabase의 메인 저장소를 클론합니다. -depth 1 옵션으로 최신 버전만 가져와서 용량을 절약합니다.

cd ~ # 홈 디렉토리 또는 원하는 디렉토리로 이동
git clone --depth 1 https://github.com/supabase/supabase.git
cd supabase

2.2 환경 변수 파일 설정 (.env)

Supabase는 .env 파일을 통해 중요한 설정을 관리합니다. supabase 디렉토리 안에 있는 .env.example 파일을 복사하여 .env 파일을 생성하고 내용을 수정합니다.

cp .env.example .env
nano .env # 또는 vim .env

nano 에디터에서 다음 변수들을 수정해야 합니다. 아래 값들은 반드시 강력하고 무작위적인 값으로 변경해야 합니다!

  • POSTGRES_PASSWORD: PostgreSQL 데이터베이스의 postgres 사용자 비밀번호. 필수!
    • 예시: POSTGRES_PASSWORD=my_strong_db_password_123
  • JWT_SECRET: Supabase 서비스 간의 통신 및 사용자 인증에 사용되는 JWT(JSON Web Token) 비밀 키. 매우 중요! 32자 이상, 무작위 문자열을 권장합니다.
    • 예시: JWT_SECRET=super_long_and_random_jwt_secret_for_supabase_0123456789
    • 무작위 문자열 생성: openssl rand -base64 32 또는 head /dev/urandom | tr -dc A-Za-z0-9_ | head -c 32 ; echo
  • ANON_KEY & SERVICE_KEY: 이 키들은 일반적으로 JWT_SECRET을 기반으로 Supabase 서비스가 자동으로 생성합니다. 초기 .env 파일에서는 빈 값으로 두거나, 임시로 아무 값이나 넣어두고 나중에 Supabase Studio에서 얻은 실제 값으로 업데이트할 수 있습니다. 초기 설정에서는 JWT_SECRET만 제대로 설정하면 됩니다.

이 외의 다른 설정들 (예: SITE_URL, SUPABASE_URL 등)은 초기 실행 후 API 도메인 설정 단계에서 다시 다룰 것입니다.

파일을 수정했으면 Ctrl+X, Y, Enter를 눌러 저장하고 종료합니다.


🚀 3단계: Supabase 초기 실행

이제 모든 준비가 끝났습니다. Docker Compose를 사용하여 Supabase 서비스를 실행해 봅시다.

supabase 디렉토리 내에서 다음 명령어를 실행합니다.

docker compose pull # 최신 Docker 이미지를 미리 다운로드
docker compose up -d # 백그라운드에서 모든 Supabase 서비스 시작

명령어를 실행하면 PostgreSQL, GoTrue (인증), PostgREST (API), Storage, Realtime 등 Supabase의 모든 핵심 컴포넌트가 Docker 컨테이너로 시작됩니다.

확인: 모든 컨테이너가 정상적으로 실행되는지 확인합니다.

docker compose ps

모든 컨테이너의 상태가 Up으로 표시되면 성공입니다! 👍

로그를 확인하여 오류가 없는지 점검할 수도 있습니다.

docker compose logs -f

🌐 4단계: API 도메인 설정 및 SSL 적용

Supabase를 프로덕션 환경에서 사용하려면 http://서버_IP:8000 대신 https://api.yourdomain.com과 같은 깔끔한 도메인을 사용하고, 보안을 위해 SSL(HTTPS)을 적용해야 합니다. 이를 위해 리버스 프록시(Reverse Proxy)를 설정하고 Let’s Encrypt를 통해 무료 SSL 인증서를 발급받을 것입니다.

4.1 DNS 설정

도메인 등록 기관(가비아, 카페24, Godaddy 등)에서 다음 서브도메인의 A 레코드를 서버의 공인 IP 주소로 연결해야 합니다.

  • api.yourdomain.com -> 서버 IP
  • auth.yourdomain.com -> 서버 IP
  • realtime.yourdomain.com -> 서버 IP
  • storage.yourdomain.com -> 서버 IP
  • functions.yourdomain.com -> 서버 IP
  • studio.yourdomain.com (선택 사항, Studio 접근용) -> 서버 IP

DNS 변경 사항이 전파되는 데 시간이 걸릴 수 있습니다 (보통 몇 분에서 몇 시간).

4.2 리버스 프록시 설정 (Nginx 예시)

Nginx를 사용하여 외부 요청을 Supabase Docker 컨테이너의 내부 포트로 전달할 것입니다.

4.2.1 Nginx 설치
sudo apt install nginx -y
4.2.2 Nginx 설정 파일 생성

/etc/nginx/sites-available/supabase.conf 파일을 생성하고 다음 내용을 추가합니다. yourdomain.com을 실제 도메인으로 변경하세요.

sudo nano /etc/nginx/sites-available/supabase.conf
# STUDIO (Optional, if you want a dedicated domain for Studio)
server {
    listen 80;
    server_name studio.yourdomain.com; # Your Studio domain
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name studio.yourdomain.com; # Your Studio domain

    ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem; # Adjust if using a separate cert
    ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem; # Adjust if using a separate cert
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://localhost:8000; # Supabase Kong Gateway
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}

# API Gateway (Kong)
server {
    listen 80;
    server_name api.yourdomain.com; # Your API domain
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name api.yourdomain.com; # Your API domain

    ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://localhost:8000; # Supabase Kong Gateway
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}

# Auth (GoTrue)
server {
    listen 80;
    server_name auth.yourdomain.com; # Your Auth domain
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name auth.yourdomain.com; # Your Auth domain

    ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://localhost:9999; # Supabase GoTrue
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}

# Storage
server {
    listen 80;
    server_name storage.yourdomain.com; # Your Storage domain
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name storage.yourdomain.com; # Your Storage domain

    ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://localhost:54321; # Supabase Storage
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}

# Realtime
server {
    listen 80;
    server_name realtime.yourdomain.com; # Your Realtime domain
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name realtime.yourdomain.com; # Your Realtime domain

    ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://localhost:54322; # Supabase Realtime
        proxy_http_version 1.1; # Required for WebSockets
        proxy_set_header Upgrade $http_upgrade; # Required for WebSockets
        proxy_set_header Connection "upgrade"; # Required for WebSockets
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}

# Functions
server {
    listen 80;
    server_name functions.yourdomain.com; # Your Functions domain
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name functions.yourdomain.com; # Your Functions domain

    ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://localhost:54323; # Supabase Functions
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }
}

설명:

  • listen 80: HTTP 요청을 받습니다.
  • return 301 https://$host$request_uri: HTTP 요청을 HTTPS로 리다이렉트합니다.
  • listen 443 ssl http2: HTTPS 요청을 받습니다.
  • server_name: 각 서브도메인을 설정합니다.
  • proxy_pass: 각 서브도메인에 해당하는 Supabase 컨테이너의 내부 포트로 요청을 전달합니다.
    • localhost:8000: Kong (API Gateway, PostgREST 포함)
    • localhost:9999: GoTrue (인증)
    • localhost:54321: Storage (스토리지)
    • localhost:54322: Realtime (실시간)
    • localhost:54323: Edge Functions (엣지 함수)
  • proxy_set_header: 원본 요청 헤더를 전달하여 Supabase 서비스가 올바른 클라이언트 IP 등을 인식하게 합니다.
  • Realtime (54322) 부분: 웹소켓 통신을 위해 proxy_http_version 1.1, Upgrade, Connection 헤더를 추가해야 합니다.
4.2.3 Nginx 설정 활성화

생성한 설정 파일을 sites-enabled 디렉토리에 심볼릭 링크로 연결하여 활성화합니다.

sudo ln -s /etc/nginx/sites-available/supabase.conf /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default # 기본 Nginx 설정 파일 비활성화 (충돌 방지)
4.2.4 Nginx 설정 테스트 및 재시작
sudo nginx -t # 설정 파일 문법 검사
sudo systemctl reload nginx # Nginx 재시작

오류가 없으면 Nginx가 정상적으로 작동할 것입니다.

4.3 SSL 인증서 발급 (Let’s Encrypt with Certbot)

Let’s Encrypt와 Certbot을 사용하여 무료 SSL 인증서를 발급받고 자동으로 갱신하도록 설정합니다.

4.3.1 Certbot 설치
sudo apt install certbot python3-certbot-nginx -y
4.3.2 SSL 인증서 발급

Nginx 플러그인을 사용하여 인증서를 발급받습니다. Nginx 설정 파일에 지정한 모든 도메인을 포함해야 합니다.

sudo certbot --nginx -d api.yourdomain.com -d auth.yourdomain.com -d realtime.yourdomain.com -d storage.yourdomain.com -d functions.yourdomain.com -d studio.yourdomain.com

안내에 따라 이메일 주소를 입력하고 약관에 동의합니다. http 트래픽을 https로 자동 리다이렉트할지 묻는 질문에는 2: Redirect를 선택하는 것이 일반적입니다.

성공적으로 완료되면 Certbot이 자동으로 Nginx 설정을 업데이트하고 SSL을 적용합니다.

4.3.3 자동 갱신 확인

Let’s Encrypt 인증서는 90일마다 갱신해야 합니다. Certbot은 자동으로 갱신 스케줄러를 등록해 줍니다. 다음 명령어로 갱신 테스트를 할 수 있습니다.

sudo certbot renew --dry-run

The dry run was successful 메시지가 보이면 자동 갱신이 잘 작동할 것입니다.

4.4 Supabase .env 파일 업데이트

이제 Supabase 서비스가 외부에서 접근 가능한 도메인을 인식하도록 .env 파일을 업데이트해야 합니다.

supabase 디렉토리로 이동하여 .env 파일을 다시 엽니다.

cd ~/supabase
nano .env

다음 변수들을 업데이트합니다:

  • SITE_URL: Supabase Studio 및 인증 리다이렉트에 사용될 기본 도메인입니다.
    • 예시: SITE_URL=https://studio.yourdomain.com (또는 https://yourdomain.com 등)
  • SUPABASE_URL: Supabase 클라이언트 SDK가 연결할 API 엔드포인트입니다.
    • 예시: SUPABASE_URL=https://api.yourdomain.com
  • PUBLIC_SUPABASE_URL: 클라이언트 측에서 사용되는 공개 Supabase URL (일반적으로 SUPABASE_URL과 동일하게 설정).
    • 예시: PUBLIC_SUPABASE_URL=https://api.yourdomain.com

ANON_KEYSERVICE_KEY: 이 키들은 Supabase Studio에서 얻을 수 있습니다. 일단 JWT_SECRET이 올바르게 설정되어 있다면, 브라우저에서 https://studio.yourdomain.com (또는 https://api.yourdomain.com으로 접속 후 로그인)에 접속하여 로그인합니다. 초기 로그인 사용자명은 supabase 이고 비밀번호는 .env 파일에 설정한 POSTGRES_PASSWORD 입니다. 로그인 후, 왼쪽 메뉴의 Project Settings -> API 섹션에서 Project API keys 아래의 anon 키와 service_role 키를 찾을 수 있습니다. 이 키들을 .env 파일의 ANON_KEYSERVICE_KEY에 정확히 붙여넣습니다.

예시 (일부만 발췌):

# ... 다른 설정들 ...
JWT_SECRET=super_long_and_random_jwt_secret_for_supabase_0123456789
# ... 다른 설정들 ...

SITE_URL=https://studio.yourdomain.com
SUPABASE_URL=https://api.yourdomain.com
PUBLIC_SUPABASE_URL=https://api.yourdomain.com

ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InlvdXJfcHJvamVjdF9pZCIsImxvbCI6ImFub24iLCJpYXQiOjE2NzgwMDM2MzQsImV4cCI6MTk5MzU3OTYzNH0.your_anon_key_from_studio
SERVICE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InlvdXJfcHJvamVjdF9pZCIsImxvbCI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTY3ODAwMzYzNCwiZXhwIjoxOTkzNTc5NjM0fQ.your_service_key_from_studio
# ... 다른 설정들 ...

.env 파일을 저장한 후, Supabase 컨테이너를 재시작하여 변경 사항을 적용합니다.

docker compose down # 기존 컨테이너 중지
docker compose up -d # 새 설정으로 컨테이너 다시 시작

✅ 5단계: 설치 확인 및 관리

이제 Supabase 셀프 호스팅 설치가 완료되었습니다!

5.1 Supabase Studio 접속

웹 브라우저에서 https://studio.yourdomain.com (또는 설정한 Studio 도메인)으로 접속합니다. 로그인 페이지가 나타나면 초기 사용자명 supabase.env에 설정한 POSTGRES_PASSWORD를 사용하여 로그인합니다.

Studio에서 프로젝트 대시보드를 확인하고, 테이블 생성, 인증 설정, 스토리지 버킷 관리 등 모든 기능을 정상적으로 사용할 수 있는지 확인해 보세요. 🎉

5.2 클라이언트 SDK 연결 테스트

이제 여러분의 애플리케이션에서 Supabase JS SDK를 사용하여 연결할 수 있습니다.

import { createClient } from '@supabase/supabase-js'

const supabaseUrl = 'https://api.yourdomain.com' // 여러분의 API 도메인
const supabaseKey = 'YOUR_ANON_KEY_FROM_STUDIO' // Studio에서 얻은 anon 키

const supabase = createClient(supabaseUrl, supabaseKey)

async function testConnection() {
  const { data, error } = await supabase
    .from('your_table_name') // 예시 테이블 이름
    .select('*')

  if (error) {
    console.error('Error:', error)
  } else {
    console.log('Data:', data)
  }
}

testConnection()

5.3 Supabase 업데이트

Supabase는 빠르게 발전하고 있습니다. 정기적으로 업데이트하여 최신 기능과 보안 패치를 적용하세요.

supabase 디렉토리에서:

git pull origin main # 최신 코드 가져오기
docker compose pull # 최신 이미지 다운로드
docker compose up -d # 컨테이너 재시작

주의: 업데이트 전에 .env 파일의 변경 사항이나 커스텀 설정이 Git 업데이트로 덮어쓰이지 않도록 백업하거나 확인하는 것이 좋습니다.

5.4 백업 전략

데이터는 가장 중요합니다! PostgreSQL 데이터베이스와 Storage 버킷 데이터를 정기적으로 백업하는 전략을 수립해야 합니다.

  • PostgreSQL 백업: pg_dump 유틸리티를 사용하여 데이터베이스를 덤프할 수 있습니다.
    docker exec -t supabase_db_1 pg_dumpall -c -U postgres > backup.sql

    (여기서 supabase_db_1docker compose ps로 확인 가능한 PostgreSQL 컨테이너 이름입니다.)

  • Storage 백업: minio 클라이언트를 사용하거나, 스토리지 데이터가 저장되는 볼륨을 직접 백업할 수 있습니다.

5.5 보안 고려사항

  • 방화벽 설정 (UFW): 서버의 방화벽(UFW 등)을 설정하여 필요한 포트만 외부에 노출시키고 나머지는 차단합니다.
    • SSH (22)
    • HTTP (80)
    • HTTPS (443)
    • Supabase 내부 포트 (8000, 9999, 54321, 54322, 54323 등)는 외부에서 직접 접근하지 못하도록 내부 네트워크에서만 허용해야 합니다.
      sudo ufw allow 22/tcp
      sudo ufw allow 80/tcp
      sudo ufw allow 443/tcp
      sudo ufw enable
  • 강력한 비밀번호: POSTGRES_PASSWORD, JWT_SECRET을 비롯한 모든 비밀번호는 강력하고 무작위적인 값으로 설정하세요.
  • 정기적인 업데이트: 운영체제, Docker, Supabase 모두 최신 상태로 유지하세요.
  • 로그 모니터링: 컨테이너 로그를 정기적으로 확인하여 비정상적인 활동이나 오류를 감지하세요.

troubleshoot 🚧 문제 해결 팁

설치 과정에서 문제가 발생할 경우 다음 사항들을 확인해 보세요.

  • 방화벽: 서버의 방화벽(UFW, Iptables)이 필요한 포트(80, 443)를 막고 있지 않은지 확인하세요.
  • DNS 전파: 도메인 DNS 설정 변경이 완전히 전파되었는지 ping이나 nslookup 명령어로 확인하세요.
  • Docker 컨테이너 상태: docker compose ps 명령어로 모든 Supabase 컨테이너가 Up 상태인지 확인하세요.
  • 로그 확인: docker compose logs [컨테이너_이름] (예: docker compose logs kong) 명령어로 특정 컨테이너의 로그를 확인하여 오류 메시지를 찾으세요.
  • Nginx 설정: sudo nginx -t 명령어로 Nginx 설정 파일에 문법 오류가 없는지 확인하고, sudo systemctl reload nginx로 Nginx를 재시작했는지 확인하세요.
  • .env 파일: JWT_SECRET, POSTGRES_PASSWORD, SITE_URL, SUPABASE_URL, ANON_KEY, SERVICE_KEY 등이 올바르게 설정되었는지 다시 확인하세요. 오타는 없는지, 따옴표 등 형식이 맞는지 주의 깊게 보세요.

🎉 마치며

이제 여러분은 Supabase를 직접 서버에 설치하고 운영할 수 있는 능력을 갖추게 되었습니다! 셀프 호스팅은 초기 설정의 번거로움이 있지만, 장기적으로 비용을 절감하고 데이터에 대한 완벽한 제어권을 가질 수 있다는 큰 장점이 있습니다.

이 가이드가 Supabase 셀프 호스팅 여정에 큰 도움이 되었기를 바랍니다. 궁금한 점이나 문제가 발생하면 Supabase 공식 문서나 커뮤니티를 참고하여 해결할 수 있습니다. 여러분의 멋진 프로젝트를 Supabase와 함께 만들어나가세요! Happy coding! 💻✨

답글 남기기

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