<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>HTTPS &#8211; Aveshost Blog</title>
	<atom:link href="https://blog.aveshost.com/tag/https/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.aveshost.com</link>
	<description>Your Blueprint for Online Success</description>
	<lastBuildDate>Wed, 04 Nov 2026 17:02:24 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.4</generator>

<image>
	<url>https://blog.aveshost.com/wp-content/uploads/2026/01/logo-150x150.png</url>
	<title>HTTPS &#8211; Aveshost Blog</title>
	<link>https://blog.aveshost.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>How to Self-Host Supabase on a VPS with Docker and HTTPS</title>
		<link>https://blog.aveshost.com/self-host-supabase-on-a-vps/</link>
					<comments>https://blog.aveshost.com/self-host-supabase-on-a-vps/#respond</comments>
		
		<dc:creator><![CDATA[James Wilson]]></dc:creator>
		<pubDate>Wed, 04 Nov 2026 16:31:21 +0000</pubDate>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Web Hosting]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[HTTPS]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[self-hosting]]></category>
		<category><![CDATA[Supabase]]></category>
		<category><![CDATA[vps]]></category>
		<guid isPermaLink="false">https://blog.aveshost.com/?p=5739</guid>

					<description><![CDATA[To self-host Supabase on a VPS with Docker and HTTPS, provision an Ubuntu server with at least 4 GB of RAM and 2 vCPU cores, install Docker Engine and the Docker Compose plugin, clone the official supabase/docker directory, replace every default secret inside the .env file (POSTGRES_PASSWORD, JWT_SECRET, ANON_KEY, SERVICE_ROLE_KEY, and DASHBOARD_PASSWORD), bind Kong’s HTTP [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">To <strong>self-host Supabase on a VPS</strong> with Docker and HTTPS, provision an Ubuntu server with at least 4 GB of RAM and 2 vCPU cores, install Docker Engine and the Docker Compose plugin, clone the official <code>supabase/docker</code> directory, replace every default secret inside the <code>.env</code> file (<code>POSTGRES_PASSWORD</code>, <code>JWT_SECRET</code>, <code>ANON_KEY</code>, <code>SERVICE_ROLE_KEY</code>, and <code>DASHBOARD_PASSWORD</code>), bind Kong’s HTTP gateway port to <code>127.0.0.1:8000</code>, and place a reverse proxy such as Caddy or Nginx with Let’s Encrypt TLS in front of port <code>8000</code>.</p>



<p class="wp-block-paragraph">Self-hosting Supabase gives you full ownership of your PostgreSQL 15 database, predictable monthly server costs, unrestricted database size up to your VPS disk capacity, and complete control over data residency—without losing the developer experience of Supabase Studio, GoTrue authentication, PostgREST auto-generated APIs, Realtime WebSockets, or S3-compatible Storage.</p>



<h2 id="key-takeaways" class="wp-block-heading">Key Takeaways</h2>



<ul class="wp-block-list">
<li><strong>Size your VPS for a 12-container stack:</strong> A production self-hosted Supabase instance runs PostgreSQL, Kong, GoTrue, PostgREST, Realtime, Storage, Supavisor, and Supabase Studio simultaneously—start with at least <strong>4 GB RAM and 2 vCPU cores</strong> (8 GB RAM recommended for active production workloads).</li>



<li><strong>Never deploy with default <code>.env.example</code> keys:</strong> Every default JWT secret and database password in the public repository is publicly known. Always generate fresh cryptographic keys before starting the containers.</li>



<li><strong>Keep port 8000 bound to localhost:</strong> Docker’s port publishing bypasses standard UFW rules if bound to <code>0.0.0.0</code>. Bind Kong to <code>127.0.0.1:8000:8000</code> and route all external traffic through an HTTPS reverse proxy on port <code>443</code>.</li>



<li><strong>Enable WebSocket upgrades on your reverse proxy:</strong> Supabase Realtime requires HTTP/1.1 <code>Upgrade</code> and <code>Connection</code> headers so live database subscriptions work over <code>wss://</code>.</li>
</ul>



<div class="wp-block-rank-math-toc-block" id="rank-math-toc"><h2>Table of Contents</h2><nav><div><div><a href="#key-takeaways">Key Takeaways</a></div><div><a href="#how-to-self-host-supabase-on-a-vps-docker-architecture-overview">How to Self-Host Supabase on a VPS: Docker Architecture Overview</a></div><div><a href="#vps-hardware-requirements-and-sizing-matrix">VPS Hardware Requirements and Sizing Matrix</a></div><div><a href="#step-1-provision-your-ubuntu-vps-dns-and-firewall">Step 1: Provision Your Ubuntu VPS, DNS, and Firewall</a></div><div><a href="#step-2-install-docker-engine-and-docker-compose-v2">Step 2: Install Docker Engine and Docker Compose v2</a></div><div><a href="#step-3-clone-the-official-supabase-docker-stack">Step 3: Clone the Official Supabase Docker Stack</a></div><div><a href="#step-4-generate-cryptographic-secrets-and-configure-env">Step 4: Generate Cryptographic Secrets and Configure .env</a></div><div><a href="#step-5-lock-down-local-ports-and-launch-the-containers">Step 5: Lock Down Local Ports and Launch the Containers</a></div><div><a href="#step-6-enable-automated-https-with-caddy-or-nginx">Step 6: Enable Automated HTTPS with Caddy or Nginx</a></div><div><a href="#production-hardening-backups-and-safe-upgrades">Production Hardening, Backups, and Safe Upgrades</a></div><div><a href="#frequently-asked-questions">Frequently Asked Questions</a></div></div></nav></div>



<h2 id="how-to-self-host-supabase-on-a-vps-docker-architecture-overview" class="wp-block-heading">How to Self-Host Supabase on a VPS: Docker Architecture Overview</h2>



<p class="wp-block-paragraph">Unlike a standalone database container, <a href="https://supabase.com/docs/guides/self-hosting/docker" target="_blank" rel="noopener noreferrer">Supabase’s official Docker setup</a> is a complete backend-as-a-service platform built around PostgreSQL. When you <strong>self-host Supabase on a VPS</strong>, you do not expose seven different microservice ports to the internet. Instead, every external client SDK request and Studio dashboard session enters through a single reverse proxy on port <code>443</code>, which forwards traffic to the internal <strong>Kong API Gateway</strong> (<code>:8000</code>).</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1536" height="1024" src="https://blog.aveshost.com/wp-content/uploads/2026/11/self-hosted-supabase-docker-architecture-aveshost.webp" alt="Self-Hosted Supabase VPS Architecture diagram showing HTTPS client traffic routed through Caddy or Nginx and Kong API Gateway to PostgreSQL 15, GoTrue, PostgREST, Realtime, Storage, Supavisor, and Supabase Studio." class="wp-image-5742" srcset="https://blog.aveshost.com/wp-content/uploads/2026/11/self-hosted-supabase-docker-architecture-aveshost.webp 1536w, https://blog.aveshost.com/wp-content/uploads/2026/11/self-hosted-supabase-docker-architecture-aveshost-300x200.webp 300w, https://blog.aveshost.com/wp-content/uploads/2026/11/self-hosted-supabase-docker-architecture-aveshost-1024x683.webp 1024w, https://blog.aveshost.com/wp-content/uploads/2026/11/self-hosted-supabase-docker-architecture-aveshost-768x512.webp 768w" sizes="(max-width: 1536px) 100vw, 1536px" /><figcaption class="wp-element-caption">How HTTPS client and dashboard traffic flows through Caddy/Nginx and Kong into the self-hosted Supabase Docker Compose network.</figcaption></figure>



<p class="wp-block-paragraph">Inside the private Docker bridge network, Kong routes each path to its dedicated container:</p>



<ul class="wp-block-list">
<li><strong><code>/rest/v1/</code> → PostgREST:</strong> Introspects your PostgreSQL schema and exposes instant, Row-Level-Security (RLS) enforced REST endpoints.</li>



<li><strong><code>/auth/v1/</code> → GoTrue:</strong> Manages user sign-ups, JWT issuance, magic links, and OAuth logins.</li>



<li><strong><code>/realtime/v1/</code> → Supabase Realtime:</strong> Broadcasts PostgreSQL logical replication changes, presence, and broadcast messages over WebSockets.</li>



<li><strong><code>/storage/v1/</code> → Storage API &amp; imgproxy:</strong> Handles file uploads, access control policies, and on-the-fly image resizing.</li>



<li><strong><code>/</code> (Root) → Supabase Studio (<code>:3000</code>):</strong> Serves the web-based visual table editor, SQL workbench, and policy manager, protected by Kong Basic Auth.</li>
</ul>



<h2 id="vps-hardware-requirements-and-sizing-matrix" class="wp-block-heading">VPS Hardware Requirements and Sizing Matrix</h2>



<p class="wp-block-paragraph">Because the Docker Compose bundle launches PostgreSQL, an Elixir virtual machine for Realtime, Kong, Vector log aggregation, Logflare analytics, Supavisor connection pooling, and the Node.js Studio interface, running on a 1 GB or 2 GB server will trigger Linux out-of-memory (OOM) kills. Use the sizing table below to select the right server tier on <a href="https://www.aveshost.com/self-managed-vps-hosting" rel="noopener">Aveshost Self-Managed VPS Hosting</a> or <a href="https://www.aveshost.com/vds-ghana" rel="noopener">Aveshost Ghana VDS</a>:</p>



<figure class="wp-block-table"><table><thead><tr><th>Deployment Profile</th><th>Minimum vCPU</th><th>Minimum RAM</th><th>Recommended Storage</th><th>Best Fit Use Case</th></tr></thead><tbody><tr><td>Staging / Internal Tools</td><td>2 vCPU Cores</td><td>4 GB RAM (+ 4 GB Swap)</td><td>40 GB SSD / NVMe</td><td>MVPs, internal dashboards, dev/staging backends</td></tr><tr><td>Standard Production SaaS</td><td>4 vCPU Cores</td><td>8 GB RAM</td><td>80–120 GB SSD / NVMe</td><td>Production web &amp; mobile apps, Realtime subscriptions, Auth</td></tr><tr><td>AI / Vector &amp; High-Throughput</td><td>6–8+ vCPU Cores</td><td>16 GB+ RAM</td><td>200 GB+ NVMe</td><td><code>pgvector</code> embeddings (e.g., <a href="https://blog.aveshost.com/build-an-ai-help-desk-with-openclaw/">AI help desks</a>), heavy concurrent writes</td></tr></tbody></table></figure>



<h2 id="step-1-provision-your-ubuntu-vps-dns-and-firewall" class="wp-block-heading">Step 1: Provision Your Ubuntu VPS, DNS, and Firewall</h2>



<p class="wp-block-paragraph">Deploy a clean <strong>Ubuntu 22.04 LTS or 24.04 LTS</strong> server and point a dedicated subdomain—such as <code>supabase.yourdomain.com</code> or <code>api.yourdomain.com</code>—to your VPS public IPv4 address using an <code>A</code> record in your DNS manager (if you need a domain, register one via <a href="https://www.aveshost.com/domains" rel="noopener">Aveshost Domains</a>). If you proxy the subdomain through Cloudflare, set SSL/TLS encryption mode to <strong>Full (Strict)</strong> after completing Step 6, and make sure security rules do not inadvertently <a href="https://blog.aveshost.com/unblock-challenges-cloudflare-com/">block verification challenges</a> on your API endpoints.</p>



<p class="wp-block-paragraph">Connect to your VPS over SSH, update system packages, create a 4 GB swap file (for resilience during container startup spikes), and configure UFW so only SSH (<code>22</code>), HTTP (<code>80</code>), and HTTPS (<code>443</code>) are open publicly:</p>



<pre class="wp-block-code"><code>sudo apt update &amp;&amp; sudo apt upgrade -y
sudo apt install -y curl git ufw openssl ca-certificates

# Create a 4 GB swap file if none exists
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# Configure UFW firewall
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable</code></pre>



<figure class="wp-block-image size-large"><img decoding="async" width="1536" height="1024" src="https://blog.aveshost.com/wp-content/uploads/2026/11/deploy-supabase-vps-docker-https-steps-aveshost.webp" alt="Six-step workflow to self-host Supabase on a VPS with Docker and HTTPS: provision VPS and firewall, install Docker and Compose, clone Supabase Docker, generate secret keys, start Docker stack, and enable HTTPS proxy." class="wp-image-5743" srcset="https://blog.aveshost.com/wp-content/uploads/2026/11/deploy-supabase-vps-docker-https-steps-aveshost.webp 1536w, https://blog.aveshost.com/wp-content/uploads/2026/11/deploy-supabase-vps-docker-https-steps-aveshost-300x200.webp 300w, https://blog.aveshost.com/wp-content/uploads/2026/11/deploy-supabase-vps-docker-https-steps-aveshost-1024x683.webp 1024w, https://blog.aveshost.com/wp-content/uploads/2026/11/deploy-supabase-vps-docker-https-steps-aveshost-768x512.webp 768w" sizes="(max-width: 1536px) 100vw, 1536px" /><figcaption class="wp-element-caption">The complete six-step workflow to self-host Supabase on an Ubuntu VPS with Docker Compose and automated HTTPS.</figcaption></figure>



<h2 id="step-2-install-docker-engine-and-docker-compose-v2" class="wp-block-heading">Step 2: Install Docker Engine and Docker Compose v2</h2>



<p class="wp-block-paragraph">Install the official Docker Engine and Docker Compose v2 plugin directly from Docker’s APT repository rather than Ubuntu’s older distribution packages:</p>



<pre class="wp-block-code"><code>curl -fsSL https://get.docker.com | sudo sh
sudo systemctl enable --now docker

# Verify Docker and Docker Compose v2
docker --version
docker compose version</code></pre>



<h2 id="step-3-clone-the-official-supabase-docker-stack" class="wp-block-heading">Step 3: Clone the Official Supabase Docker Stack</h2>



<p class="wp-block-paragraph">The main Supabase monorepo is large, so use a shallow clone to download only the latest commit, copy the <code>docker/</code> deployment folder to <code>/opt/supabase</code>, and create your working <code>.env</code> file from <code>.env.example</code>:</p>



<pre class="wp-block-code"><code>sudo mkdir -p /opt/supabase
cd /opt
sudo git clone --depth 1 https://github.com/supabase/supabase.git supabase-repo
sudo cp -rf /opt/supabase-repo/docker/* /opt/supabase/
sudo cp /opt/supabase-repo/docker/.env.example /opt/supabase/.env
sudo rm -rf /opt/supabase-repo
cd /opt/supabase</code></pre>



<h2 id="step-4-generate-cryptographic-secrets-and-configure-env" class="wp-block-heading">Step 4: Generate Cryptographic Secrets and Configure .env</h2>



<p class="wp-block-paragraph">Before starting the containers, you must replace the placeholder credentials in <code>/opt/supabase/.env</code>. Every service in the cluster relies on these core variables:</p>



<figure class="wp-block-table"><table><thead><tr><th>Environment Variable</th><th>Purpose</th><th>Security Requirement</th></tr></thead><tbody><tr><td><code>POSTGRES_PASSWORD</code></td><td>Master password for the PostgreSQL database</td><td>32+ character alphanumeric string (avoid <code>@</code>, <code>:</code>, or <code>/</code> to prevent URI parsing errors)</td></tr><tr><td><code>JWT_SECRET</code></td><td>HMAC-SHA256 signing secret used by GoTrue, Kong, and PostgREST</td><td>At least 32–64 random characters</td></tr><tr><td><code>ANON_KEY</code></td><td>Public client JWT (<code>role: "anon"</code>) signed with your <code>JWT_SECRET</code></td><td>Safe for frontend SDKs; strictly enforces PostgreSQL Row Level Security (RLS)</td></tr><tr><td><code>SERVICE_ROLE_KEY</code></td><td>Admin server JWT (<code>role: "service_role"</code>) signed with your <code>JWT_SECRET</code></td><td>Bypasses RLS completely; keep strictly on backend servers, never in browser code</td></tr><tr><td><code>DASHBOARD_PASSWORD</code></td><td>Password for Supabase Studio basic authentication</td><td>Strong unique password paired with a custom <code>DASHBOARD_USERNAME</code></td></tr><tr><td><code>SECRET_KEY_BASE</code> &amp; <code>VAULT_ENC_KEY</code></td><td>Encryption keys for Realtime and Supabase Vault</td><td>64-character secret base and exact 32-character Vault key</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Run the official key-generation helper included in <code>/opt/supabase</code> (or generate secrets with OpenSSL):</p>



<pre class="wp-block-code"><code>cd /opt/supabase
# Option A: Run Supabase's built-in secret generator script
sudo bash ./utils/generate-keys.sh

# Option B: Generate clean alphanumeric secrets manually if needed
openssl rand -hex 24   # Use for POSTGRES_PASSWORD and DASHBOARD_PASSWORD
openssl rand -hex 32   # Use for JWT_SECRET and SECRET_KEY_BASE
openssl rand -hex 16   # Use for VAULT_ENC_KEY (32 hex chars)</code></pre>



<p class="wp-block-paragraph">Next, open <code>/opt/supabase/.env</code> (<code>sudo nano /opt/supabase/.env</code>) and set your public HTTPS domain and transactional email settings (if you need a free transactional relay for testing auth emails, see our guide on <a href="https://blog.aveshost.com/use-gmail-smtp-server/">how to use the Gmail SMTP server</a>):</p>



<pre class="wp-block-code"><code>SITE_URL=https://app.yourdomain.com
API_EXTERNAL_URL=https://supabase.yourdomain.com
SUPABASE_PUBLIC_URL=https://supabase.yourdomain.com

DASHBOARD_USERNAME=avesadmin
DASHBOARD_PASSWORD=YourStrongDashboardPasswordHere

SMTP_ADMIN_EMAIL=admin@yourdomain.com
SMTP_HOST=smtp.yourdomain.com
SMTP_PORT=587
SMTP_USER=smtp-user@yourdomain.com
SMTP_PASS=YourSmtpPassword
SMTP_SENDER_NAME=YourApp</code></pre>



<h2 id="step-5-lock-down-local-ports-and-launch-the-containers" class="wp-block-heading">Step 5: Lock Down Local Ports and Launch the Containers</h2>



<p class="wp-block-paragraph">By default, Docker’s port mapping (<code>8000:8000</code>) binds to <code>0.0.0.0</code> and manipulates <code>iptables</code> directly, which exposes unencrypted HTTP port <code>8000</code> to the public internet even when UFW is enabled. To prevent anyone from bypassing your HTTPS reverse proxy, bind Kong’s ports to <code>127.0.0.1</code> inside <code>/opt/supabase/docker-compose.yml</code>:</p>



<pre class="wp-block-code"><code># Inside /opt/supabase/docker-compose.yml under the kong service:
    ports:
      - 127.0.0.1:8000:8000/tcp
      - 127.0.0.1:8443:8443/tcp</code></pre>



<p class="wp-block-paragraph">Now pull the container images and launch the stack in detached mode:</p>



<pre class="wp-block-code"><code>cd /opt/supabase
sudo docker compose pull
sudo docker compose up -d

# Check that all services report "healthy"
sudo docker compose ps</code></pre>



<p class="wp-block-paragraph">Verify locally that Kong responds on port <code>8000</code> by running <code>curl -I http://127.0.0.1:8000</code> (it should return an HTTP <code>401 Unauthorized</code> prompt from Kong’s Basic Auth gate protecting Studio).</p>



<h2 id="step-6-enable-automated-https-with-caddy-or-nginx" class="wp-block-heading">Step 6: Enable Automated HTTPS with Caddy or Nginx</h2>



<p class="wp-block-paragraph">To serve your Supabase Studio dashboard and client APIs (<code>https://supabase.yourdomain.com</code>) over TLS with automatic certificate renewal and full WebSocket (<code>wss://</code>) support, install <strong>Caddy</strong> (the simplest single-file option) or <strong>Nginx + Certbot</strong>.</p>



<h3 id="option-a-caddy-reverse-proxy-automatic-lets-encrypt-ssl" class="wp-block-heading">Option A: Caddy Reverse Proxy (Automatic Let’s Encrypt SSL)</h3>



<pre class="wp-block-code"><code>sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update &amp;&amp; sudo apt install -y caddy</code></pre>



<p class="wp-block-paragraph">Replace <code>/etc/caddy/Caddyfile</code> with the following configuration (replace <code>supabase.yourdomain.com</code> with your actual subdomain):</p>



<pre class="wp-block-code"><code>supabase.yourdomain.com {
    encode zstd gzip
    reverse_proxy 127.0.0.1:8000
}</code></pre>



<p class="wp-block-paragraph">Reload Caddy (<code>sudo systemctl reload caddy</code>). Caddy automatically provisions a Let’s Encrypt TLS certificate, redirects HTTP to HTTPS, and forwards WebSocket upgrades to Kong (<code>127.0.0.1:8000</code>).</p>



<h3 id="option-b-nginx-certbot-with-websocket-upgrade-headers" class="wp-block-heading">Option B: Nginx + Certbot (With WebSocket Upgrade Headers)</h3>



<p class="wp-block-paragraph">If your server already runs Nginx, make sure your server block includes <code>Upgrade</code> and <code>Connection</code> headers so Supabase Realtime WebSockets work properly, then run <code>sudo certbot --nginx -d supabase.yourdomain.com</code>:</p>



<pre class="wp-block-code"><code>map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    server_name supabase.yourdomain.com;
    client_max_body_size 50M;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 86400;
    }
}</code></pre>



<p class="wp-block-paragraph">You can now open <code>https://supabase.yourdomain.com</code> in your browser, sign in with your <code>DASHBOARD_USERNAME</code> and <code>DASHBOARD_PASSWORD</code>, and connect your frontend or backend apps using:</p>



<pre class="wp-block-code"><code>import { createClient } from '@supabase/supabase-js'

const supabase = createClient(
  'https://supabase.yourdomain.com',
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
)</code></pre>



<h2 id="production-hardening-backups-and-safe-upgrades" class="wp-block-heading">Production Hardening, Backups, and Safe Upgrades</h2>



<ul class="wp-block-list">
<li><strong>Automate Nightly PostgreSQL Backups:</strong> Schedule a cron job that runs <code>docker exec supabase-db pg_dumpall -U postgres | gzip &gt; /backups/supabase.sql.gz</code> and syncs encrypted archives to off-site object storage.</li>



<li><strong>Enable Row Level Security (RLS) on Every Public Table:</strong> Because the <code>ANON_KEY</code> is embedded in browser and mobile apps, any table in the <code>public</code> schema without RLS enabled is readable and writable by anyone with your URL and anon key.</li>



<li><strong>Restrict Studio Access by IP (Optional):</strong> For high-security environments, restrict the Studio dashboard path in Caddy or Nginx to your office VPN IP while leaving <code>/rest/v1/</code>, <code>/auth/v1/</code>, <code>/realtime/v1/</code>, and <code>/storage/v1/</code> open to public client apps.</li>
</ul>



<p class="wp-block-paragraph">Ready to deploy your own high-performance Supabase cluster? Launch an Ubuntu server on <a href="https://www.aveshost.com/self-managed-vps-hosting" rel="noopener">Aveshost Self-Managed VPS Hosting</a> for full root control, choose <a href="https://www.aveshost.com/vds-ghana" rel="noopener">Aveshost Ghana VDS</a> for dedicated local NVMe performance, or select <a href="https://www.aveshost.com/fully-managed-vps-hosting" rel="noopener">Aveshost Fully Managed VPS Hosting</a> if you want our engineering team to handle server administration, firewall hardening, and monitoring for you.</p>



<h2 id="frequently-asked-questions" class="wp-block-heading">Frequently Asked Questions</h2>


<div id="rank-math-faq" class="rank-math-block">
<div class="rank-math-list ">
<div id="faq-question-sb-1" class="rank-math-list-item">
<h3 class="rank-math-question ">How much RAM do I need to self-host Supabase on a VPS?</h3>
<div class="rank-math-answer ">

<p>You need at least <strong>4 GB of RAM and 2 vCPU cores</strong> (plus a 4 GB swap file) to run the complete self-hosted Supabase Docker Compose stack reliably. For production applications with active users, Realtime WebSockets, or <code>pgvector</code> queries, <strong>8 GB of RAM and 4 vCPU cores</strong> is recommended.</p>

</div>
</div>
<div id="faq-question-sb-2" class="rank-math-list-item">
<h3 class="rank-math-question ">Is self-hosting Supabase free?</h3>
<div class="rank-math-answer ">

<p>Yes. Supabase is 100% open-source under OSI-approved licenses (primarily Apache 2.0 and MIT). There are no software licensing fees to self-host Supabase; you only pay for your underlying VPS infrastructure, domain name, and optional off-site backup storage.</p>

</div>
</div>
<div id="faq-question-sb-3" class="rank-math-list-item">
<h3 class="rank-math-question ">Can I host multiple Supabase projects on a single VPS?</h3>
<div class="rank-math-answer ">

<p>A single self-hosted Supabase Docker Compose stack is designed around one PostgreSQL cluster and one Studio project. You can either isolate multiple apps inside the same cluster using separate PostgreSQL schemas and Row Level Security policies, or run separate Docker Compose stacks on a larger VPS (16+ GB RAM) by assigning distinct container names and Kong ports in each stack’s <code>.env</code> file.</p>

</div>
</div>
<div id="faq-question-sb-4" class="rank-math-list-item">
<h3 class="rank-math-question ">How do I update a self-hosted Supabase Docker instance safely?</h3>
<div class="rank-math-answer ">

<p>First, take a full database backup using <code>pg_dumpall</code> and back up your <code>/opt/supabase/.env</code> and <code>volumes/</code> directory. Then pull the updated <code>docker-compose.yml</code> from the official repository, run <code>sudo docker compose pull</code>, and restart the stack with <code>sudo docker compose up -d</code>.</p>

</div>
</div>
<div id="faq-question-sb-5" class="rank-math-list-item">
<h3 class="rank-math-question ">Does self-hosted Supabase include Edge Functions and Storage?</h3>
<div class="rank-math-answer ">

<p>Yes. The official <code>supabase/docker</code> Compose stack includes the local <code>supabase/edge-runtime</code> container for Deno Edge Functions (loaded from <code>volumes/functions/</code>) as well as the S3-compatible <code>supabase/storage-api</code> and <code>imgproxy</code> containers for file uploads and image transformations.</p>

</div>
</div>
</div>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://blog.aveshost.com/self-host-supabase-on-a-vps/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
