Supabase Series: Complete Setup for running Supabase Locally

Using Next.js + Supabase + React + Typescript + Github Actions + Vercel to setup a complete fullstack web app

In this blog, we are using NextJS and Supabase. I struggled to find any resources on setting up a local environment that worked well and any decently sized production application should be recreatable from scratch using the repo. I have been using Laravel for a while and I love how database migrations are done easily.

In this blog post, we set up a simple local dev environment and create a Github action script to migrate it to the production database in Supabase.io.

Create repo

npx create-next-app supabase-local --typescript

cd supabase-local

npm install --save @supabase/supabase-js

Download and Install Docker desktop

You will have to download Docker Desktop.

For Mac OS using brew.

brew install --cask docker

For other operating systems: https://www.docker.com/products/docker-desktop

Install Supabase CLI

The Supabase team has created a great CLI to setup all the with Docker Compose.

// Install Supabase Globally
npm install -g supabase
// Initalize Supabase, this creates a .supabase folder with all the docker files.
supabase init

You will get something like this.

✔ Port for Supabase URL: · 8000
✔ Port for PostgreSQL database: · 5432
✔ Project initialized.
Supabase URL: <http://localhost:8000>
Supabase Key (anon, public): eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsImlhdCI6MTYwMzk2ODgzNCwiZXhwIjoyNTUwNjUzNjM0LCJyb2xlIjoiYW5vbiJ9.36fUebxgx1mcBo4s19v0SzqmzunP--hm_hep0uLX0ew
Supabase Key (service_role, private): eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsImlhdCI6MTYwMzk2ODgzNCwiZXhwIjoyNTUwNjUzNjM0LCJyb2xlIjoiYW5vbiJ9.36fUebxgx1mcBo4s19v0SzqmzunP--hm_hep0uLX0ew
Database URL: postgres://postgres:postgres@localhost:5432/postgres

Save these values in a environment variable, .env.local

NEXT_PUBLIC_SUPABASE_URL=http://localhost:8000
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsImlhdCI6MTYwMzk2ODgzNCwiZXhwIjoyNTUwNjUzNjM0LCJyb2xlIjoiYW5vbiJ9.36fUebxgx1mcBo4s19v0SzqmzunP--hm_hep0uLX0ew
NEXT_SUPABASE_SERVICE_ROLE_KEY=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsImlhdCI6MTYwMzk2ODgzNCwiZXhwIjoyNTUwNjUzNjM0LCJyb2xlIjoiYW5vbiJ9.36fUebxgx1mcBo4s19v0SzqmzunP--hm_hep0uLX0ew
DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres

Install Flyway

We are using Flyway to keep track of our changes database changes using migration files.

If you are using windows you can checkout the https://flywaydb.org/ guide on setting up.

To install on Mac OS (using brew):

brew install flyway

Create a file in your root directory called flyway.conf

flyway.url=jdbc:postgresql://localhost:5432/postgres
flyway.user=postgres
flyway.password=postgres
flyway.baselineOnMigrate=true
flyway.schemas=public

Run the project and start Supabase DB locally.

supabase start
npm start 

Create Table using Flyway

Create a folder called sql in your root directory with your first migration in the folder  called V1__create_projects_table.sql

create table projects (
	id serial not null primary key,
	name varchar(255) not null
);

Run Flyway migrate to create tables using the migration files:

flyway migrate

Setup Supabase Client

Create a folder called utils to contain all your helper functions and api services. In this folder, create a supabase-client.ts

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

export const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL ?? '',
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY ?? '',
);

Write Github Actions to migrate the DB when to pushed to master

You will need to set up a CI/CD script for the migration you push to master. To create the new tables in the database 😃 . I am using Github actions in this instance.

Create a file called in .github/production.yml.

You will need to define SUPABASE_PASS_PROD in your Github secrets.

name: 'Migrate database schema - production'

on:
  push:
    branches:
      - main

jobs:
  migrate-database:
    name: Run Flyway migrations
    runs-on: ubuntu-20.04
    env:
      SUPABASE_HOST: db.yimvzlnhgkmjsdknvbyoths.supabase.co // This a example URL
      SUPABASE_PORT: 5432
      SUPABASE_USER: postgres
      SUPABASE_DB: postgres
    steps:
      - uses: actions/checkout@v2
      - run: >-
          docker run --rm
          --volume ${{ github.workspace }}/sql:/flyway/sql:ro
          flyway/flyway:7.12.1-alpine
          -url="jdbc:postgresql://${{ env.SUPABASE_HOST }}:${{ env.SUPABASE_PORT }}/${{ env.SUPABASE_DB }}?sslmode=require"
          -user="${{ env.SUPABASE_USER }}"
          -password="${{ secrets.SUPABASE_PASS_PROD }}"
          migrate

Thanks for reading. Hope this helps and saves you time.

You have any questions, 📥 Follow me on Twitter

Subscribe to Ahmed Mire

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe