add caddy and nginx configs for self-hosted

This commit is contained in:
Andrey A. authored and GitHub committed 2026-03-03 14:04:35 +01:00
1 parent 911eb03498
commit 997999779f
5 files changed
+231

No files matched your search

+19
View File
@@ -217,3 +217,22 @@ KONG_HTTPS_PORT=8443
# Enable webp support
IMGPROXY_ENABLE_WEBP_DETECTION=true
############
# TLS Proxy - Optional Caddy or Nginx reverse proxy with Let's Encrypt
############
# Documentation:
# https://supabase.com/docs/guides/self-hosting/self-hosted-proxy-https
# Usage:
# docker compose -f docker-compose.yml -f docker-compose.caddy.yml up -d
# docker compose -f docker-compose.yml -f docker-compose.nginx.yml up -d
# Domain name for the proxy (must point to your server)
PROXY_DOMAIN=your-domain.example.com
# Email for Let's Encrypt certificate notifications (nginx only, Caddy uses PROXY_DOMAIN).
# This should be a valid email, not a placehoder (otherwise Certbot may fail to start).
CERTBOT_EMAIL=admin@example.com
+34
View File
@@ -0,0 +1,34 @@
services:
kong:
ports: !reset []
caddy:
container_name: supabase-caddy
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
depends_on:
kong:
condition: service_healthy
environment:
PROXY_DOMAIN: ${PROXY_DOMAIN}
PROXY_AUTH_USERNAME: ${DASHBOARD_USERNAME}
PROXY_AUTH_PASSWORD: ${DASHBOARD_PASSWORD}
command:
- /bin/sh
- -c
- |
PROXY_AUTH_PASSWORD=$$(caddy hash-password --plaintext "$$PROXY_AUTH_PASSWORD") && \
caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
volumes:
- ./volumes/proxy/caddy:/etc/caddy
- caddy_data:/data
- caddy_config:/config
volumes:
caddy_data:
caddy_config:
+33
View File
@@ -0,0 +1,33 @@
services:
kong:
ports: !reset []
nginx:
container_name: supabase-nginx
image: jonasal/nginx-certbot:6.0.1-nginx1.29.5
restart: unless-stopped
ports:
- "80:80"
- "443:443"
depends_on:
kong:
condition: service_healthy
environment:
PROXY_DOMAIN: ${PROXY_DOMAIN}
CERTBOT_EMAIL: ${CERTBOT_EMAIL}
PROXY_AUTH_USERNAME: ${DASHBOARD_USERNAME}
PROXY_AUTH_PASSWORD: ${DASHBOARD_PASSWORD}
command:
- /bin/bash
- -c
- |
printf '%s:%s\n' "$${PROXY_AUTH_USERNAME}" "$$(openssl passwd -apr1 "$${PROXY_AUTH_PASSWORD}")" > /etc/nginx/user_conf.d/dashboard-passwd && \
envsubst '$${PROXY_DOMAIN}' < /etc/nginx/supabase-nginx.conf.tpl > /etc/nginx/user_conf.d/nginx.conf && \
/scripts/start_nginx_certbot.sh
volumes:
- ./volumes/proxy/nginx/supabase-nginx.conf.tpl:/etc/nginx/supabase-nginx.conf.tpl:ro
- nginx_letsencrypt:/etc/letsencrypt
volumes:
nginx_letsencrypt:
+36
View File
@@ -0,0 +1,36 @@
{$PROXY_DOMAIN} {
@supabase_api path /auth/v1/* /rest/v1/* /graphql/v1/* /realtime/v1/* /functions/v1/* /mcp
handle @supabase_api {
reverse_proxy kong:8000
}
handle_path /storage/v1/* {
# CORS headers for Storage (bypasses Kong, which normally handles CORS)
@cors_preflight method OPTIONS
handle @cors_preflight {
header Access-Control-Allow-Origin *
header Access-Control-Allow-Methods "GET, HEAD, PUT, PATCH, POST, DELETE, OPTIONS"
header Access-Control-Allow-Headers *
respond 204
}
header Access-Control-Allow-Origin *
reverse_proxy storage:5000 {
# Required for TUS resumable upload Location headers and S3 signature verification.
header_up X-Forwarded-Prefix /{http.request.orig_uri.path.0}/{http.request.orig_uri.path.1}
}
}
handle {
basic_auth {
# PROXY_AUTH_PASSWORD is overwritten with the bcrypt on startup
{$PROXY_AUTH_USERNAME} {$PROXY_AUTH_PASSWORD}
}
reverse_proxy studio:3000
}
header -server
}
@@ -0,0 +1,109 @@
upstream kong_upstream {
server kong:8000;
keepalive 2;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name ${PROXY_DOMAIN};
server_tokens off;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
ssl_certificate /etc/letsencrypt/live/${PROXY_DOMAIN}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${PROXY_DOMAIN}/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/${PROXY_DOMAIN}/chain.pem;
ssl_dhparam /etc/letsencrypt/dhparams/dhparam.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Prevent 502 errors from large Supabase auth cookies
large_client_header_buffers 4 16k;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
location / {
auth_basic "supabase";
auth_basic_user_file /etc/nginx/user_conf.d/dashboard-passwd;
proxy_pass http://studio:3000;
}
location /auth {
proxy_pass http://kong_upstream;
}
location /rest {
proxy_pass http://kong_upstream;
}
location /realtime/v1/ {
proxy_pass http://kong_upstream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
location /storage/v1/ {
proxy_pass http://storage:5000/;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
# Required for TUS resumable upload Location headers and S3 signature verification.
proxy_set_header X-Forwarded-Prefix /storage/v1;
client_max_body_size 0;
# CORS headers for Storage (bypasses Kong, which normally handles CORS)
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, HEAD, PUT, PATCH, POST, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' '*';
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain charset=UTF-8';
return 204;
}
add_header 'Access-Control-Allow-Origin' '*';
}
location /functions {
proxy_pass http://kong_upstream;
}
location /graphql {
proxy_pass http://kong_upstream;
}
location /mcp {
proxy_pass http://kong_upstream;
}
}