Supabase는 오픈소스 플랫폼으로 Docker를 통해 셀프호스팅을 할 수 있다.
Self-Hosting with Docker - Supabase 공식문서도 제공한다.
공식문서에 나오지 않은 부분들을 추가로 조사하여 정리하였다.
- 예시 env 수정하기 - Postgres Pass 워드 변경 적용 등
- OAuth를 위한 환경변수 추가하기
- 엔진엑스 프록시 메니저를 위한 네트워크 추가
- pg_dump를 통해 클라우드의 데이터 베이스 내보내기
s3 서버 연결을 위한 환경변수
Logflare를 위한 환경변수
Supabase 복사하기
먼저 아래와 같은 명령어를 터미널에 입력하여 Supabase를 복사한다.
# 깃허브의 최신 커밋 클론하기
git clone --depth 1 https://github.com/supabase/supabase
# 새로운 프로젝트 폴더 만들기
mkdir supabase-project
# 현재 폴더구조
# .
# ├── supabase
# └── supabase-project
# supabase 폴더에서 프로젝트 폴더로 필요한 파일 복사하기
cp -rf supabase/docker/* supabase-project
cp supabase/docker/.env.example supabase-project/.env
# 프로젝트 폴더로 이동하기
cd supabase-project
깃허브의 최신 커밋을 클론받아 예제들을 supabase-project로 복사하엿다.
env 수정하기
프로젝트 폴더에 예시를 복사한 .env
파일이 있다. 해당 .env
파일을 수정하여 호스팅하면 된다.
POSTGRES_PASSWORD=your-super-secret-and-long-postgres-password
JWT_SECRET=your-super-secret-jwt-token-with-at-least-32-characters-long
ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE
SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q
DASHBOARD_USERNAME=supabase
DASHBOARD_PASSWORD=this_password_is_insecure_and_should_be_updated
SECRET_KEY_BASE=UpNVntn3cDxHJpq99YMc1T1AQgQpc8kfYTuRgBiYa15BLrx8etQoXz3gZv1/u2oq
VAULT_ENC_KEY=your-encryption-key-32-chars-min
POSTGRES_PASSWORD
: DB 접근을 위한 비밀번호이다. env를 수정한 후 Postgres에 접속하여 수정하여야 한다. 깃허브 토론을 참고하여 바뀐 비밀번호를 Postgres에 적용할 수 있다. 직접 DB에 접근할 일이 없으므로 강하고 어려운 비밀번호로 지정한다.
JWT_SECRET
, ANON_KEY
, SERVICE_ROLE_KEY
: jwt시크릿을 토대로 익명키과 서비스키를 생성하게 된다. Self-Hosting with Docker - Supabase 공식문서에 세 가지를 묶어서 생성하는 도구가 있다.
DASHBOARD_USERNAME
, DASHBOARD_PASSWORD
: 대시보드에 접속할 때 사용하는 아이디와 비밀번호이다. 자주 사용해야 하므로 기억하기 좋은 걸로 지정한다.
SECRET_KEY_BASE
, VAULT_ENC_KEY
: 각각 토큰 서명, 대칭키 암호화에 사용되는 암호화키들이다. 외부에 유출되지 않아야 하고, 직접 입력할 일이 없으므로 어려운 키로 입력한다.
POSTGRES_PASSWORD
, SECRET_KEY_BASE
, VAULT_ENC_KEY
와 같이 어려운 암호를 만들어야 할 때에는 shell에서 아래와 같은 방식으로 base64 문자열이나 32바이트 문자열을 만들면 된다.
openssl rand -base64 64
openssl rand -hex 32
OAuth 연결하기
Supabase는 GoTrue를 사용한다. 원하는 서비스 프로바이더의 OAuth가 있으면 검색하면 적용하는 예제들이 나온다.
대시보드에서 OAuth를 적용하는 기능을 제공하지 않으므로 env파일과 도커 이미지를 통해서 추가해주어야 한다.
Google OAuth를 추가하려면 env에 아래와 같이 입력한다.
############
# Auth - Configuration for the GoTrue authentication server.
############
# ...rest
# Google Auth
ENABLE_GOOGLE_SIGNUP = true
GOOGLE_CLIENT_ID = 클라이언트.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET = GOCSPX-클라이언트시크릿
GOOGLE_CALLBACK_URI = https://슈퍼베이스-배포될-주소/auth/v1/callback
ADDITIONAL_REDIRECT_URLS=http://localhost:3000/callback,https://클라이언트-주소/callback
GOOGLE_CLIENT_ID
, GOOGLE_CLIENT_SECRET
, GOOGLE_CALLBACK_URI
는 구글 클라우드 콘솔의 API 콘솔에서 확인할 수 있다. (이 블로그의 12. Supabase 인증 구현 참고)
ADDITIONAL_REDIRECT_URLS
는 사용되는 클라이언트가 여러 곳일 경우 위와 같이 쉼표를 통해 입력해준다.
docker-compose.yml
에 아래를 추가해준다.
services:
#...rest
auth:
container_name: supabase-auth
# ...rest
environment:
# ...rest
GOTRUE_EXTERNAL_GOOGLE_ENABLED: ${ENABLE_GOOGLE_SIGNUP}
GOTRUE_EXTERNAL_GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
GOTRUE_EXTERNAL_GOOGLE_SECRET: ${GOOGLE_CLIENT_SECRET}
GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI: ${GOOGLE_CALLBACK_URI}
프록시
먼저 Nginx-Proxy-Manager 등을 이용하여 리버스 프록시를 하고 싶은 경우, supabase-kong
으로 프록시를 해주면 된다. 나의 경우 npm-network
라는 리버스 프록시에 사용하는 네트워크가 있어 이를 연결해주었다.
services:
#...rest
kong:
container_name: supabase-kong
#...rest
ports:
- ${KONG_HTTP_PORT}:8000/tcp
- ${KONG_HTTPS_PORT}:8443/tcp
#...rest
networks:
- npm-network
- default
#...rest
# 최하단에 네트워크 정의 추가
networks:
npm-network:
external: true
default:
name: supabase_default
kong
을 외부 네트워크로 연결하면서 기존 네트워크도 함께 연결해야 다른 서비스와 연결되는데, 기본적으로 supabase의 서비스들은 supabase_default
라는 네트워크들로 연결되어 있다. 해당 네트워크를 default
라는 이름으로 받아와 연결한다.
env
파일에서는 배포와 함께 아래의 변수들을 수정해주어야 한다.
KONG_HTTP_PORT=8000
SITE_URL=http://localhost:3000
API_EXTERNAL_URL=http://localhost:8000
SUPABASE_PUBLIC_URL=http://localhost:8000
KONG_HTTP_PORT
: 요청을 받을 포트번호
SITE_URL
: 클라이언트의 주소. 즉 Next.js 등에서 접속할 때에는 localhost:3000
이고 이미 배포주소가 있는 클라이언트에서 접속할 때에는 https://배포된주소
로 지정해야 한다.
API_EXTERNAL_URL
, SUPABASE_PUBLIC_URL
: 배포된 슈퍼베이스의 주소이다.
위와 같이 배포 전과 후에 따라 달라지는 env가 있음을 확인할 수 있다.
편안한 개발을 위해서는 로컬용 도커와 배포용 도커의 env를 따로 나누어서 관리하는 것이 좋다.
한편 Complete Guide ⚡️ Supabase Self-Hosted ➕ Custom S3 ➕ Authelia -
activenode YouTube
Complete Guide ⚡️ Supabase Self-Hosted ➕ Custom S3 ➕ Authelia -
activenode YouTube
영상에서는 kong
에 포트 바인딩을 없애고 직접 엔진엑스 프록시매니저와 연결하는 방법을 다룬다.
기타 (마이그레이션, 커스텀S3, 모니터링)
PG_DUMP로 마이그레이션
슈퍼베이스는 pg_dump를 지원한다.
DB 연결 주소 조회
https://supabase.com/dashboard/project/{프로젝트_id}/database/settings?showConnect=true
와 같이 showConnet=true로 쿼리 스트링을 넣으면 클라우드DB에 접속할 수 있는 주소들이 나온다.
Direct connection
주소를 통해 pg_dumb에 접속할 수 있지만, 해당 주소가 작동하지 않는 경우 Session pooler
로 대체하여 사용한다.
아래와 같이 Session pooler
주소가 조회된다.
postgresql://{프로젝트id}:[YOUR-PASSWORD]@aws-0-ap-northeast-2.pooler.supabase.com:5432/postgres
PG_DUMP 다운로드
pg_dump \
--no-owner \
--format=custom \
--dbname "postgresql://{프로젝트id}:[YOUR-PASSWORD]@aws-0-ap-northeast-2.pooler.supabase.com:5432/postgres" \
-f /tmp/backup.dump \
&& /tmp/backup.dump ~/Downloads/backup_$(date +%Y%m%d_%H%M%S).dump
위와 같은 명령어를 입력하면 backup 이라는 이름으로 (맥북의) 다운로드 폴더로 저장된다.
pg_dump에 관한 설명은 pg_dump - Postgrest 공식문서
커스텀S3
참고
Complete Guide ⚡️ Supabase Self-Hosted ➕ Custom S3 ➕ Authelia -
activenode YouTube
Complete Guide ⚡️ Supabase Self-Hosted ➕ Custom S3 ➕ Authelia -
activenode YouTube
The ultimate Supabase self-hosting Guide - DavidLorenz(activenode) Blog
Supabase를 셀프호스팅하면 Supabase는 임의의 볼륨에 이미지를 업로드하고 다운로드할 수 있도록 지원한다.
하지만 S3 서버 등으로 파일저장소를 별도로 분리하여 호스팅한 후 연결할 수 있다.
먼저 minio를 이용해 백엔드 서버에 S3처럼 사용하는 볼륨을 만들기 위해서는 단순하게 아래와 같은 명령어로 실행할 수 있다.
docker compose -f docker-compose.yml -f docker-compose.s3.yml up
docker-compose.s3.yml이 추가적으로 이미지를 빌드하면서 s3처럼 사용되는 minio 볼륨을 추가해준다.
만일 AWA와 같은 S3 서버로 연결하고자 하면 docker-compose.s3.yml
의 supabase-storage 컨테이너를 다음과 같이 수정한다.
storage:
container_name: supabase-storage
# ...rest
environment:
# ...rest
GLOBAL_S3_BUCKET: my-bucket-name # S3 버킷 이름
GLOBAL_S3_ENDPOINT: https://s3.amazonaws.com # AWS S3 기본 엔드포인트
GLOBAL_S3_PROTOCOL: https
GLOBAL_S3_FORCE_PATH_STYLE: false # AWS는 보통 false
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
AWS_DEFAULT_REGION: ap-northeast-2 # 서울 리전 예시
# ...rest
volumes:
- ./volumes/storage:/var/lib/storage:z
모니터링
참고
Self-Hosting Analytics - Supabase 공식문서
슈퍼베이스는 Logflare와 postgres를 통한 백엔드 로그를 지원한다.
로그플레어 사이트에서 계정을 만든 후 .env
에서 아래의 두 환경변수를 수정해주면 된다.
LOGFLARE_PUBLIC_ACCESS_TOKEN=your-super-secret-and-long-logflare-key-public
LOGFLARE_PRIVATE_ACCESS_TOKEN=your-super-secret-and-long-logflare-key-private
postgres를 통한 로그 관리는 안정적이지만, 프로덕트 레벨에서는 구글 클라우드의 BigQuery를 이용하는 것이 권장된다.
BigQuery를 사용하기 위해서는 .env
에서 아래의 환경변수를 수정해준다.
# Google Cloud Project details
GOOGLE_PROJECT_ID=GOOGLE_PROJECT_ID
GOOGLE_PROJECT_NUMBER=GOOGLE_PROJECT_NUMBER
그리고 docker-compose.yml
에서는 구글 클라우드 플랫폼을 위한 볼륨을 추가하고,
Postgres를 이용하기 위한 환경변수는 주석처리하면 된다.
services:
# ...rest
analytics:
container_name: supabase-analytics
# ...rest
ports:
- 4000:4000
# 빅쿼리를 위한 볼륨 추가
volumes:
- type: bind
source: ${PWD}/gcloud.json
target: /opt/app/rel/logflare/bin/gcloud.json
read_only: true
# ...rest
environment:
# ...rest
# Postgres 입력을 위한 환경변수들 주석처리
# POSTGRES_BACKEND_URL: postgresql://supabase_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/_supabase
# POSTGRES_BACKEND_SCHEMA: _analytics
# LOGFLARE_FEATURE_FLAG_OVERRIDE: multibackend=true
# 구글 BigQuery를 사용하는데 필요한 id와 number 추가
GOOGLE_PROJECT_ID: ${GOOGLE_PROJECT_ID}
GOOGLE_PROJECT_NUMBER: ${GOOGLE_PROJECT_NUMBER}