193 lines
6.3 KiB
Bash
193 lines
6.3 KiB
Bash
#!/bin/bash
|
|
# Supabase Self-Hosted Deployment Script for Mylder VPS
|
|
# Run this script on the VPS as root
|
|
|
|
set -e
|
|
|
|
echo "=== Supabase Self-Hosted Deployment ==="
|
|
echo ""
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Configuration
|
|
SUPABASE_DIR="/srv/supabase"
|
|
COMPOSE_FILE="$SUPABASE_DIR/docker-compose.yml"
|
|
ENV_FILE="$SUPABASE_DIR/.env"
|
|
|
|
# Step 1: Create directory structure
|
|
echo -e "${YELLOW}Step 1: Creating directory structure...${NC}"
|
|
mkdir -p $SUPABASE_DIR/volumes/{api,db/data,db/init,storage,functions/main,logs}
|
|
cd $SUPABASE_DIR
|
|
|
|
# Step 2: Generate secrets
|
|
echo -e "${YELLOW}Step 2: Generating secrets...${NC}"
|
|
POSTGRES_PASSWORD=$(openssl rand -hex 24)
|
|
JWT_SECRET=$(openssl rand -hex 32)
|
|
SECRET_KEY_BASE=$(openssl rand -base64 48 | tr -d '\n')
|
|
VAULT_ENC_KEY=$(openssl rand -hex 16)
|
|
PG_META_CRYPTO_KEY=$(openssl rand -hex 16)
|
|
DASHBOARD_PASSWORD=$(openssl rand -base64 16 | tr -d '\n')
|
|
LOGFLARE_API_KEY=$(openssl rand -hex 16)
|
|
|
|
echo -e "${GREEN}Generated secrets (save these!):${NC}"
|
|
echo "POSTGRES_PASSWORD: $POSTGRES_PASSWORD"
|
|
echo "JWT_SECRET: $JWT_SECRET"
|
|
echo "DASHBOARD_PASSWORD: $DASHBOARD_PASSWORD"
|
|
|
|
# Step 3: Generate JWT tokens
|
|
echo -e "${YELLOW}Step 3: Generating JWT tokens...${NC}"
|
|
|
|
# Install Node.js jwt-cli if not present
|
|
if ! command -v node &> /dev/null; then
|
|
echo "Node.js not found. Installing..."
|
|
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
|
apt-get install -y nodejs
|
|
fi
|
|
|
|
# Generate ANON and SERVICE_ROLE keys using Node.js
|
|
ANON_KEY=$(node -e "
|
|
const crypto = require('crypto');
|
|
const header = Buffer.from(JSON.stringify({alg:'HS256',typ:'JWT'})).toString('base64url');
|
|
const payload = Buffer.from(JSON.stringify({role:'anon',iss:'supabase',iat:Math.floor(Date.now()/1000),exp:Math.floor(Date.now()/1000)+315360000})).toString('base64url');
|
|
const signature = crypto.createHmac('sha256','$JWT_SECRET').update(header+'.'+payload).digest('base64url');
|
|
console.log(header+'.'+payload+'.'+signature);
|
|
")
|
|
|
|
SERVICE_ROLE_KEY=$(node -e "
|
|
const crypto = require('crypto');
|
|
const header = Buffer.from(JSON.stringify({alg:'HS256',typ:'JWT'})).toString('base64url');
|
|
const payload = Buffer.from(JSON.stringify({role:'service_role',iss:'supabase',iat:Math.floor(Date.now()/1000),exp:Math.floor(Date.now()/1000)+315360000})).toString('base64url');
|
|
const signature = crypto.createHmac('sha256','$JWT_SECRET').update(header+'.'+payload).digest('base64url');
|
|
console.log(header+'.'+payload+'.'+signature);
|
|
")
|
|
|
|
echo "ANON_KEY: $ANON_KEY"
|
|
echo "SERVICE_ROLE_KEY: $SERVICE_ROLE_KEY"
|
|
|
|
# Step 4: Create .env file
|
|
echo -e "${YELLOW}Step 4: Creating .env file...${NC}"
|
|
cat > $ENV_FILE << EOF
|
|
############################################################
|
|
# SECRETS
|
|
############################################################
|
|
POSTGRES_PASSWORD=$POSTGRES_PASSWORD
|
|
JWT_SECRET=$JWT_SECRET
|
|
ANON_KEY=$ANON_KEY
|
|
SERVICE_ROLE_KEY=$SERVICE_ROLE_KEY
|
|
DASHBOARD_USERNAME=admin
|
|
DASHBOARD_PASSWORD=$DASHBOARD_PASSWORD
|
|
SECRET_KEY_BASE=$SECRET_KEY_BASE
|
|
VAULT_ENC_KEY=$VAULT_ENC_KEY
|
|
PG_META_CRYPTO_KEY=$PG_META_CRYPTO_KEY
|
|
|
|
############################################################
|
|
# DATABASE
|
|
############################################################
|
|
POSTGRES_DB=postgres
|
|
POSTGRES_PORT=5432
|
|
PGRST_DB_SCHEMAS=public,storage,graphql_public
|
|
|
|
############################################################
|
|
# URLS
|
|
############################################################
|
|
SITE_URL=https://mylder.io
|
|
API_EXTERNAL_URL=https://supabase.mylder.io
|
|
SUPABASE_PUBLIC_URL=https://supabase.mylder.io
|
|
ADDITIONAL_REDIRECT_URLS=
|
|
|
|
############################################################
|
|
# AUTH
|
|
############################################################
|
|
JWT_EXPIRY=3600
|
|
DISABLE_SIGNUP=false
|
|
ENABLE_EMAIL_SIGNUP=true
|
|
ENABLE_EMAIL_AUTOCONFIRM=false
|
|
ENABLE_ANONYMOUS_SIGN_INS=false
|
|
ENABLE_PHONE_SIGNUP=false
|
|
ENABLE_PHONE_AUTOCONFIRM=false
|
|
|
|
############################################################
|
|
# SMTP (configure with Mailjet API keys)
|
|
# Get keys from: https://app.mailjet.com/account/apikeys
|
|
############################################################
|
|
SMTP_ADMIN_EMAIL=admin@mylder.io
|
|
SMTP_HOST=in-v3.mailjet.com
|
|
SMTP_PORT=587
|
|
SMTP_USER=f42a859cc0e03f91af90849be4c981fc
|
|
SMTP_PASS=22fc7cbc55e4b515702b5264f4b1636e
|
|
SMTP_SENDER_NAME=Mylder
|
|
|
|
MAILER_URLPATHS_INVITE=/auth/v1/verify
|
|
MAILER_URLPATHS_CONFIRMATION=/auth/v1/verify
|
|
MAILER_URLPATHS_RECOVERY=/auth/v1/verify
|
|
MAILER_URLPATHS_EMAIL_CHANGE=/auth/v1/verify
|
|
|
|
############################################################
|
|
# STUDIO
|
|
############################################################
|
|
STUDIO_DEFAULT_ORGANIZATION=Mylder
|
|
STUDIO_DEFAULT_PROJECT=Main
|
|
IMGPROXY_ENABLE_WEBP_DETECTION=true
|
|
|
|
############################################################
|
|
# FUNCTIONS & ANALYTICS
|
|
############################################################
|
|
FUNCTIONS_VERIFY_JWT=true
|
|
LOGFLARE_API_KEY=$LOGFLARE_API_KEY
|
|
EOF
|
|
|
|
chmod 600 $ENV_FILE
|
|
echo -e "${GREEN}.env file created${NC}"
|
|
|
|
# Step 5: Check if docker-compose.yml exists
|
|
if [ ! -f "$COMPOSE_FILE" ]; then
|
|
echo -e "${RED}docker-compose.yml not found at $COMPOSE_FILE${NC}"
|
|
echo "Please copy the docker-compose.yml file to $SUPABASE_DIR"
|
|
exit 1
|
|
fi
|
|
|
|
# Step 6: Check if kong.yml exists
|
|
if [ ! -f "$SUPABASE_DIR/volumes/api/kong.yml" ]; then
|
|
echo -e "${RED}kong.yml not found${NC}"
|
|
echo "Please copy volumes/api/kong.yml to $SUPABASE_DIR/volumes/api/"
|
|
exit 1
|
|
fi
|
|
|
|
# Step 7: Pull images
|
|
echo -e "${YELLOW}Step 5: Pulling Docker images...${NC}"
|
|
docker compose pull
|
|
|
|
# Step 8: Start services
|
|
echo -e "${YELLOW}Step 6: Starting Supabase services...${NC}"
|
|
docker compose up -d
|
|
|
|
# Step 9: Wait for health checks
|
|
echo -e "${YELLOW}Step 7: Waiting for services to be healthy...${NC}"
|
|
sleep 30
|
|
|
|
# Step 10: Check status
|
|
echo -e "${YELLOW}Step 8: Checking service status...${NC}"
|
|
docker compose ps
|
|
|
|
echo ""
|
|
echo -e "${GREEN}=== Deployment Complete ===${NC}"
|
|
echo ""
|
|
echo "Access Supabase Studio at: https://supabase.mylder.io"
|
|
echo "Username: admin"
|
|
echo "Password: $DASHBOARD_PASSWORD"
|
|
echo ""
|
|
echo "API URL: https://supabase.mylder.io"
|
|
echo "ANON_KEY: $ANON_KEY"
|
|
echo "SERVICE_ROLE_KEY: $SERVICE_ROLE_KEY"
|
|
echo ""
|
|
echo -e "${YELLOW}IMPORTANT: Save these credentials securely!${NC}"
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo "1. Add DNS A record for supabase.mylder.io pointing to this server"
|
|
echo "2. Configure SMTP (replace SMTP_USER/SMTP_PASS in .env with Mailjet API keys)"
|
|
echo "3. Access Studio and create your database schema"
|