Back to articles
Technology Insight

Bringing Serverless Home: A Comprehensive Guide to Self-Hosting Supabase Edge Functions (Deno) on a VPS

June 6, 2026

Introduction: The Promise and Price of Serverless

Serverless architecture has revolutionized how modern developers build and deploy backend logic. By abstracting away server management, platforms like AWS Lambda, Vercel, and Supabase Functions allow engineering teams to focus strictly on writing business logic. However, as applications scale, the cost of serverless computing can become unpredictable, and the inherent risk of vendor lock-in grows.

Supabase has emerged as a powerhouse open-source alternative to Firebase, offering a deeply integrated suite of tools including a PostgreSQL database, Authentication, Storage, and Realtime capabilities. At the heart of its serverless offering are Supabase Edge Functions, powered by Deno—a secure, fast runtime for JavaScript and TypeScript. While Supabase's managed cloud platform is excellent, certain enterprise compliance requirements, data sovereignty laws, or cost-optimization strategies mandate a shift toward self-hosting.

This comprehensive technical guide will demonstrate how to bring serverless home by self-hosting the Supabase Edge Functions infrastructure on your own Virtual Private Server (VPS), maximizing control while retaining the lightweight development workflow of Deno.

Why Self-Host Supabase Edge Functions?

Before diving into the configuration, it is essential to understand the structural advantages of running your own Edge Functions infrastructure on a standard VPS:

  • Cost Predictability: Instead of being billed per million executions or gigabyte-seconds, you pay a flat monthly rate for your VPS infrastructure.
  • Reduced Latency: If your core database and application services are already co-located on a private network or specific regional VPS, hosting your functions nearby eliminates unnecessary internet round-trips.
  • Data Sovereignty and Compliance: For industries bound by strict regulations (such as GDPR or HIPAA), self-hosting ensures that your data and runtime logs never leave your managed infrastructure boundaries.
  • No Execution Time Limits: Managed platforms enforce hard timeouts on edge functions. On your own VPS, you can tune these limits to accommodate long-running tasks or heavy background processing.

Understanding the Self-Hosted Architecture

To successfully run Supabase Edge Functions on a VPS, we rely on the open-source core components that power the Supabase platform. The central piece of this architecture is Edge Runtime, an open-source server developed by Supabase specifically designed to execute Deno scripts securely and efficiently via V8 isolates.

Unlike traditional Node.js applications that require a heavy memory footprint per instance, Deno utilized within Edge Runtime spins up lightweight V8 isolates. This architecture allows hundreds of functions to run concurrently with minimal overhead, making it highly suitable for resource-constrained VPS environments.

To orchestrate this, we will deploy the ecosystem using Docker and Docker Compose, routing incoming HTTP traffic through a reverse proxy (like Nginx, Traefik, or the Supabase Kong API Gateway) directly to the Edge Runtime container.

Prerequisites and Environment Setup

Before proceeding, ensure your environment meets the following requirements:

  1. A VPS running a modern Linux distribution (e.g., Ubuntu 22.04 LTS or later) with at least 2GB of RAM and a public IP address.
  2. Docker and Docker Compose installed on the host machine.
  3. The Supabase CLI installed on your local development machine.
  4. A domain name pointed at your VPS IP address for SSL termination.

Step-by-Step Deployment Blueprint

Step 1: Preparing the VPS Directory Structure

Log into your VPS via SSH and create a dedicated directory structure to manage your self-hosted Supabase infrastructure:

mkdir -p ~/supabase-serverless/volumes/functions
cd ~/supabase-serverless

The volumes/functions directory will store the compiled or raw TypeScript files representing your individual Edge Functions.

Step 2: Configuring the Docker Compose Environment

Create a docker-compose.yml file in your root folder. This configuration sets up the official Supabase Edge Runtime image and links it to your network configuration. Below is a production-ready blueprint:

version: '3.8'

services:
  edge_runtime:
    image: supabase/edge-runtime:v1.53.1
    container_name: supabase-edge-runtime
    restart: always
    ports:
      - "8081:8081"
    environment:
      - JWT_SECRET=${JWT_SECRET}
      - SUPABASE_URL=${SUPABASE_URL}
      - SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}
      - SUPABASE_SERVICE_ROLE_KEY=${SUPABASE_SERVICE_ROLE_KEY}
    volumes:
      - ./volumes/functions:/home/deno/functions
    command:
      - start
      - --main-service
      - /home/deno/functions/main

In this architecture, the --main-service flag instructs the runtime to look for a routing entry point. You will also need to create a .env file in the same directory to securely store your JWT secrets and API keys used for authentication vetting.

Step 3: Creating the Function Router

Unlike the managed Supabase Cloud which dynamically routes URLs to your functions automatically, the self-hosted Edge Runtime utilizes a centralized entry file (often named main/index.ts) to handle routing. Inside your volumes/functions directory, create a folder named main and an index.ts file:

import { serve } from "[https://deno.land/[email protected]/http/server.ts](https://deno.land/[email protected]/http/server.ts)"

serve(async (req) => {
  const url = new URL(req.url);
  const pathSegments = url.pathname.split('/').filter(Boolean);
  const functionName = pathSegments[0];

  try {
    // Dynamic routing based on the URL path segment
    const module = await import(`../${functionName}/index.ts`);
    return await module.default(req);
  } catch (err) {
    return new Response(JSON.stringify({ error: `Function '${functionName}' not found.` }), {
      status: 404,
      headers: { "Content-Type": "application/json" },
    });
  }
})

Step 4: Writing Your First Edge Function

Now, create an actual functional endpoint. Create a directory named hello-world under volumes/functions/ and add an index.ts file:

export default async function handler(req: Request) { 
  const data = { message: "Hello from your self-hosted Supabase Edge Function running on Deno!" };
  return new Response(JSON.stringify(data), {
    headers: { "Content-Type": "application/json" },
    status: 200
  });
}

Step 5: Launching and Testing the Ecosystem

With your environment variables configured and files in place, initiate your system using Docker Compose:

docker compose up -d

Validate that your server is listening on port 8081 by triggering a test curl request:

curl http://localhost:8081/hello-world

If configured correctly, the endpoint will execute your Deno code seamlessly and return the JSON response instantaneously.

Production Hardening and Best Practices

Deploying to production requires additional operational safeguards to guarantee security and system uptime:

1. Reverse Proxy and SSL Termination

Never expose the raw Edge Runtime port directly to the public internet. Deploy a reverse proxy like Nginx or Caddy in front of your container. This handles HTTPS encryption using Let's Encrypt certificates, manages HTTP/2 optimization, and provides a layer of defense against volumetric distributed denial-of-service (DDoS) attacks.

2. Securing Endpoints via JWT Verification

Supabase Edge Functions are secure by default because they validate JSON Web Tokens (JWT) issued by your system's auth service. In your custom router or individual functions, read the Authorization header and decode it against your JWT_SECRET using standard Deno JWT validation libraries to block unauthenticated requests.

3. Memory and Resource Constraints

To avoid a rogue function draining your entire VPS resources, utilize Docker’s built-in resource limits. Restrict CPU and memory parameters directly inside your docker-compose.yml file:

deploy:
  resources:
    limits:
      cpus: '0.50'
      memory: 512M

Conclusion: True Infrastructure Autonomy

Self-hosting Supabase Edge Functions bridges the gap between modern cloud developer experiences and classic infrastructure ownership. By wrapping the powerful Deno-based Edge Runtime inside a lightweight VPS deployment, you achieve unprecedented cost control, localized execution latencies, and total transparency over your backend architecture. Whether running isolated proof-of-concepts or high-throughput production enterprise backends, the power to run serverless is now entirely in your hands.