/supabase-on-do

Primary LanguageHCLApache License 2.0Apache-2.0

Supabase on DigitalOcean

Supabase is a backend-as-a-service platform built around the Postgres database, and is an Open Source alternative to Firebase. It can reduce time to market by providing a ready to use backend that includes a database with real time capabilities, authentication, object storage and edge functions. You can use Supabase as a service via their managed offerings or self-host it on your own server or on a cloud provider.

Running Supabase on DigitalOcean

We will self-host Supabase by deploying the following architecture. Supabase on DigitalOcean

Docker Compose

The components that make up Supabase will be running via a docker-compose.yml file. The following is taken directly from the Supabase self-hosting documentation page and provides a description of each of its components:

  • Kong is a cloud-native API gateway.
  • GoTrue is an SWT based API for managing users and issuing SWT tokens.
  • PostgREST is a web server that turns your PostgreSQL database directly into a RESTful API
  • Realtime is an Elixir server that allows you to listen to PostgreSQL inserts, updates, and deletes using websockets. Realtime pollsPostgres' built-in replication functionality for database changes, converts changes to JSON, then broadcasts the JSON over websockets to authorized clients.
  • Storage provides a RESTful interface for managing Files stored in S3, using Postgres to manage permissions.
  • postgres-meta is a RESTful API for managing your Postgres, allowing you to fetch tables, add roles, and run queries, etc.
  • PostgreSQL is an object-relational database system with over 30 years of active development that has earned it a strong reputation for reliability, feature robustness, and performance.

In addition to the above components, the docker-compose file also runs swag. SWAG (Secure Web Application Gateway) provides an Nginx webserver and reverse proxy with a built-in certbot client that automates free SSL certificate generation and renewal. It also contains fail2ban for added intrusion prevention. As swag deploys Nginx we will also use it to setup basic authentication to protect access to studio (the dashboard component of Supabase).

DigitalOcean Components

All of the above will be running on a DigitalOcean Droplet. Persistent storage for the database is provided via a Volume attached to the Droplet and object storage, for artifacts like profile pics and more, will be achieved using Spaces. A Domain, Reserved IP and Firewall are also setup to ensure we can securely access our Supabase instance from the web.

SendGrid

Supabase's auth component, GoTrue, requires the ability to send emails. As DigitalOcean blocks Port 25 on all Droplets for new accounts (IP reputation being a main reason for this as well as other factors) we will use SendGrid to send emails. SendGrid offers a generous free plan of 100 emails/day which should suffice for most use cases.

Packer and Terraform

At DigitalOcean simplicity in all we DO is one of our core values, and automating as much as possible of our processes enables us to achieve this. In this regard we will use Packer and Terraform to automate the build and provision the resources.

Pre-requisites

The Manual Part

  • Create a DigitalOcean API token with read/write permissions (docs)
  • Create a DO Spaces access key and secret (docs)
  • Create a Domain in DO and change nameservers in your domain registrar (docs)
  • Create an admin (full access) SendGrid API token (docs)
  • (Optional) If using Terraform Cloud to manage your state file, create a user API token

The (Semi-)Automated Part

We're going to run some cli commands within our terminal which can be automated within a CI/CD process.

Once we've setup and created all of the above, clone the repository:

git clone https://github.com/digitalocean/supabase-on-do.git
cd supabase-on-do
  1. After cloning the repo, our next step is to build a snapshot of the Droplet we will be running, by following the documentation in the packer directory.
  2. Finally we will deploy our resources using terraform as specified here.

TLDR

Or the - I didn't want to read the next sections, just give me the commands to run, I trust you - version

Run Packer to create the Snapshot

## From the root of the repository change directory to the packer directory
cd packer

## Copy the example file to supabase.auto.pkrvars.hcl, modify it with your own variables and save
cp supabase.auto.pkrvars.hcl.example supabase.auto.pkrvars.hcl
## Initialise packer to download any plugin binaries needed
packer init .

## Build the snapshot and upload it as a Snapshot on DO
packer build .

Run Terraform to create the resources

## From the root of the repository change directory to the terraform directory
## (from the packer directory  use ../terraform)
cd terraform

## Copy the example file to terraform.tfvars, modify it with your own variables and save
cp terraform.tfvars.example terraform.tfvars
## Initialise terraform to download any plugin binaries needed
terraform init

## Create and show a plan of what will be created
## (skip if you want to apply immediately)
terraform plan

## Apply the changes specified by confirming at the prompt
## (--auto-approve if you're feeling adventures)
terraform apply

## Apply again to verify the SendGrid components
## (needed as they are created before the domain records in DO)
terraform apply

Show generated passwords and tokens for later use

## Show the generated auth password
terraform output htpasswd

## Show the generated psql password
terraform output psql_pass

## Show the generated jwt secret and tokens
terraform output jwt
terraform output jwt_anon
terraform output jwt_service_role

Take a 5-10 min break and after that point your browser to supabase.${your-domain}. When the pop-up asking for your auth details appears enter your provided username and the generated htpasswd.

Enjoy and Happy creating :)