Deploying Self-Hosted Supabase on AWS EC2: Complete Guide

Deploy self-hosted Supabase on AWS EC2 step by step: instance sizing, Docker setup, security groups, S3 backups, and honest costs vs RDS and Supabase Cloud.

Cover Image for Deploying Self-Hosted Supabase on AWS EC2: Complete Guide

Your startup has $5,000 in AWS credits, your company already runs everything in a VPC, or your compliance team simply won't approve another vendor. Whatever the reason, you want self-hosted Supabase on AWS—and EC2 is the most direct way to get it. Unlike the budget VPS providers most self-hosters start with, AWS brings IAM roles, native S3, EBS snapshots, and a bill that can quietly triple if you're not careful.

This guide walks through deploying the full Supabase stack on an EC2 instance: choosing the right instance type, locking down security groups, running the Docker Compose stack, and wiring backups to S3 the AWS-native way. We'll also be honest about when EC2 is the wrong choice.

Why EC2 (and When It Isn't the Right Call)

EC2 is the simplest AWS deployment target for Supabase: one VM, Docker Compose, done. It's a good fit when:

  • You have AWS credits to burn. Activate and founder programs hand out credits that cover a year or more of hosting.
  • Your other infrastructure is already on AWS. Keeping Supabase in the same VPC as your app servers means private networking, no public database exposure, and no cross-cloud egress fees.
  • Compliance requires it. If your organization has an approved AWS environment with existing audit controls, deploying inside it is far easier than onboarding a new provider.

When it isn't the right call:

  • Pure price-performance. A Hetzner or OVH box gives you 2–4x the compute per dollar. If you're not tied to AWS, the true cost of self-hosting is much lower elsewhere.
  • You wanted managed Postgres anyway. If you're considering EC2 + RDS, pause. Supabase's images ship extensions and roles that RDS doesn't support out of the box, and you lose the single-stack simplicity. It's possible, but it's a different (harder) project.
  • You need orchestration. For multi-node setups, ECS or Kubernetes with Helm makes more sense than hand-managing EC2 instances—at a significant complexity cost.

Sizing Your Instance

The full Supabase stack (Postgres, Auth, PostgREST, Realtime, Storage, Studio, gateway, and the analytics container) needs roughly 2–4 GB of RAM just to idle comfortably. Our system requirements guide covers the details, but for EC2 specifically:

InstancevCPU / RAMOn-demand (us-east-1)Good for
t3.medium2 / 4 GB~$30/moDev, staging, small production
t3.large2 / 8 GB~$60/moMost production workloads
t4g.large (ARM)2 / 8 GB~$49/moProduction, ~20% cheaper
m7g.large2 / 8 GB~$58/moSustained CPU (no burst credits)

Two AWS-specific notes:

Graviton (ARM) works. Supabase publishes multi-arch images, and t4g/m7g instances are meaningfully cheaper. See our ARM64 deployment guide for the gotchas.

Watch burst credits on t3/t4g. Burstable instances throttle hard when CPU credits run out—which looks exactly like a mysterious database slowdown at 3 AM. For sustained load, use t3.unlimited mode (and monitor the surcharge) or move to m-family.

For storage, use gp3 EBS (not gp2): 20 GB minimum, and you get 3,000 IOPS baseline regardless of volume size—better and cheaper than gp2's size-scaled IOPS.

Launching and Locking Down the Instance

  1. Launch an Ubuntu 24.04 LTS instance in your target region.
  2. Security group: allow inbound 443 (and 80 for ACME challenges) from 0.0.0.0/0, and 22 only from your IP or via SSM Session Manager. Do not open 5432 or 8000 to the world. If your app servers live in the same VPC, allow 5432 from their security group only—this is one of EC2's genuine advantages over a public VPS.
  3. Allocate an Elastic IP and associate it, so your DNS doesn't break when the instance restarts.
  4. Attach an IAM role (we'll use it for S3 backups later—no access keys on disk).

Installing the Stack

SSH in and install Docker:

sudo apt update && sudo apt upgrade -y
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker ubuntu

Then pull the official Supabase Docker setup:

git clone --depth 1 https://github.com/supabase/supabase
cd supabase/docker
cp .env.example .env

Before starting anything, edit .env and replace every default secret: POSTGRES_PASSWORD, JWT_SECRET, ANON_KEY, SERVICE_ROLE_KEY, DASHBOARD_PASSWORD, and the encryption keys. The defaults are publicly documented; leaving them in place is the single most common way self-hosted instances get compromised.

Two things worth knowing in 2026: the default database image is now Postgres 17 (if you depend on TimescaleDB or plv8, check extension availability before upgrading), and Supabase is switching the default self-hosted gateway from Kong to Envoy in August 2026. If you're deploying fresh, start with the Envoy compose file so you're not migrating in a month—our June 2026 breaking changes guide covers the transition.

Then:

docker compose pull
docker compose up -d

One AWS-specific gotcha: Docker Hub rate-limits anonymous pulls (100 per 6 hours per IP). On a single EC2 instance with its own Elastic IP you'll rarely hit it, but if you're behind a shared NAT gateway, authenticate with a free Docker Hub account before pulling.

For production hardening—resource limits, restart policies, log rotation—follow our Docker Compose production best practices before you point real traffic at this box.

TLS and Domains

Don't rely on the gateway's built-in HTTPS (Kong's listener is one of the things breaking in the Envoy migration anyway). Put a reverse proxy—Caddy is the least-effort option—in front of the stack to terminate TLS with Let's Encrypt, and point your API and Studio subdomains at the Elastic IP.

Skip AWS's ALB + ACM route unless you need it: an ALB adds ~$18/month plus LCU charges for something Caddy does for free on a single instance.

Backups: Where AWS Actually Shines

This is the best part of running Supabase on EC2. S3 is right there, in-region, with no egress fees between your instance and the bucket.

Create a bucket, then attach a policy to your instance's IAM role:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": ["s3:PutObject", "s3:GetObject", "s3:ListBucket"],
    "Resource": [
      "arn:aws:s3:::my-supabase-backups",
      "arn:aws:s3:::my-supabase-backups/*"
    ]
  }]
}

Because the role is attached to the instance, your backup tooling picks up credentials automatically—no long-lived access keys sitting in a .env file. Add a lifecycle rule to transition old backups to Glacier and expire them after your retention window.

Two warnings from the trenches:

  • EBS snapshots are not database backups. A snapshot of a running Postgres volume is crash-consistent at best. Use them as a secondary layer, not your recovery plan. You need logical dumps or WAL archiving—see creating backups for approaches that actually restore.
  • Don't forget Storage files. Your uploaded files live in a Docker volume, not the database. Storage backup is the forgotten piece of most self-hosted setups.

Supascale automates this whole layer: scheduled Postgres and Storage backups to any S3-compatible bucket with one-click restore, configured through a UI instead of cron scripts. See the backup storage docs for wiring it to your AWS bucket.

The Real Monthly Bill

AWS pricing has sharp edges that VPS providers don't. A realistic small-production setup:

ItemCost
t3.large (on-demand)~$60
50 GB gp3 EBS~$4
Elastic IP (attached)~$3.60
S3 backups (50 GB)~$1.15
Egress (100 GB to internet)~$9
Total~$78/mo

Egress is the trap: at $0.09/GB, an app serving lots of images or video from Supabase Storage can make bandwidth your biggest line item—the same workload on Hetzner includes 20 TB free. A 1-year reserved instance or savings plan cuts the compute cost ~40% and brings this closer to $55/month.

Compare that with Supabase Cloud's $25/month Pro tier and the math is honest: on AWS you're paying for control, VPC integration, or credits—not raw savings. With credits, of course, the math is simply "free for a year."

Managing It After Day One

Deployment is one afternoon. The ongoing work—health monitoring, upgrades, backup verification, credential rotation—is what actually costs you. That's the gap Supascale fills: it manages your Supabase instances on any server, including EC2, with automated S3 backups, custom domains with SSL, OAuth configuration, and health monitoring—for a one-time $39.99 purchase with unlimited projects, instead of a monthly subscription.

Point Supascale at a fresh Ubuntu EC2 instance and the installation guide gets you from empty VM to running project without hand-editing a single .env file.

Further Reading