News & Updates

How to Spin Up Supabase Locally With Docker Compose

By Jonathan Pierce 8 min read 4062 views

How to Spin Up Supabase Locally With Docker Compose

Running Supabase in a containerized environment is a game‑changer for front‑end developers who want a full‑stack backend without cloud latency. By wiring Supabase together with Docker Compose, you get PostgreSQL, Kong, Realtime, and the Auth service all on your laptop, ready in seconds. The following guide walks you through the exact steps, from prerequisite checks to troubleshooting those annoying “service not reachable” messages.

Why Use Docker Compose for Supabase?

Docker Compose bundles multiple containers into a single, declarative file. That means you can start—or stop—the entire Supabase stack with one command instead of juggling separate Docker run calls. It also mirrors the production architecture, so the code you write locally behaves the same way when you deploy to Vercel, Netlify, or any other host.

Prerequisites Before You Begin

  • Docker Engine (latest stable version recommended)
  • Docker Compose (v2+ provides the docker compose sub‑command)
  • Git for cloning the starter repository
  • Optional but handy: Node.js or any runtime you plan to connect to Supabase

Make sure each tool is accessible from your terminal; a quick docker --version and docker compose version should confirm everything is in order.

Step‑by‑Step: Building the Compose File

The core of the setup lives in a docker-compose.yml file placed at the root of your project. Below is a minimal configuration that pulls the official Supabase Docker images and wires them together.

Version and Services

Start with version: "3.8" and declare four services: postgres, kong, realtime, and auth. Each service maps its default port to a host port, so you can reach them from your browser or CLI.

Environment Variables

Supabase relies heavily on environment variables for secrets and URLs. In the postgres block, set POSTGRES_PASSWORD. For auth and realtime, define SUPABASE_URL, SUPABASE_ANON_KEY, and JWT_SECRET. You can keep these values in a separate .env file and reference it with env_file: .env.

Network

All services sit on a custom network (e.g., supabase_network) to ensure they can resolve each other by name. This mimics the internal DNS that Supabase uses in production.

Once the file is saved, run docker compose config to verify the syntax—Docker will point out any misplaced indentation before you even start the containers.

Launching the Stack

With the compose file ready, fire up the whole backend by executing:

docker compose up -d

The -d flag detaches the process, leaving the containers running in the background. You can monitor their health with docker compose ps, which shows each service’s status and exposed ports. Expect PostgreSQL to be reachable at localhost:5432, Kong at localhost:8000, and the Supabase dashboard at localhost:3000.

Connecting Your App to the Local Supabase Instance

When initializing the Supabase client in your front‑end code, point the URL to http://localhost:8000 (Kong) and use the anon key from your .env. For example, in a JavaScript project:

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

const supabase = createClient('http://localhost:8000', process.env.VITE_SUPABASE_ANON_KEY);

Because the stack runs locally, network latency drops to near zero, making real‑time updates feel instantaneous during development.

Common Pitfalls and How to Fix Them

  • Port conflicts: If another service already occupies port 5432 or 8000, change the host mapping in docker-compose.yml (e.g., 5433:5432).
  • Missing environment variables: Forgetting JWT_SECRET will cause Auth to fail at startup. Double‑check your .env file for all required keys.
  • Container health checks: Occasionally a container may start before its dependency is ready (e.g., Realtime before Postgres). Adding depends_on with condition: service_healthy can enforce proper ordering.
  • Data persistence: By default, Docker volumes are temporary. Define a named volume for Postgres (e.g., postgres_data:/var/lib/postgresql/data) to keep your tables across restarts.

Tips for Faster Iteration

  • Use docker compose restart <service> instead of tearing down the whole stack when tweaking a single container.
  • Leverage docker compose logs -f <service> to tail logs in real time, which is invaluable for spotting Auth token errors.
  • Keep your .env under version control (excluding secrets) so new teammates can spin up an identical environment with a single docker compose up.
  • Consider adding healthcheck directives to each service; Docker will automatically retry failed containers, saving you manual restarts.

FAQ

Do I need a Supabase account to run the local stack?

No. The Docker images contain the open‑source components needed for a full Supabase experience. An account only becomes necessary when you push data to the hosted Supabase platform.

Can I run the stack on Windows?

Absolutely. Docker Desktop for Windows supports both Docker Engine and Compose. Just make sure you enable the WSL 2 backend for the best performance.

How do I reset the database without deleting volumes?

Run docker compose exec postgres psql -U postgres -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;". This clears all tables while preserving the volume configuration.

Is it safe to expose the local Supabase URL to the internet?

Generally no. The local setup lacks production‑grade security hardening. If you must share it, tunnel the connection through a service like ngrok and enforce strong JWT secrets.

Alberto Sadde
Development Environment Setup | SET09102 Software Engineering
What Is Docker Compose? Simplifying Multi-Container Apps
How to Build Docker Compose for Local Development

Written by Jonathan Pierce

Jonathan Pierce is a Chief Correspondent with over a decade of experience covering breaking trends, in-depth analysis, and exclusive insights.