### Create Configuration File Source: https://github.com/drizzle-team/fastabase/blob/main/README.md Copy the example configuration file to create your own `config.yaml`. You will need to fill in the specific values for your deployment. ```shell cp config.yaml.example config.yaml ``` -------------------------------- ### Install Dependencies Source: https://github.com/drizzle-team/fastabase/blob/main/README.md Install all project dependencies using pnpm. Ensure you have Node.js 22 and pnpm installed. ```shell pnpm i ``` -------------------------------- ### Fastabase Deployment Commands Source: https://context7.com/drizzle-team/fastabase/llms.txt Provides commands for cloning, configuring, installing dependencies, setting AWS credentials, and deploying Fastabase core stacks and Supabase Studio. Includes commands for retrieving outputs and removing resources. ```shell # Prerequisites node --version # must be >= 22 pnpm --version # 1. Clone and init submodules (includes supabase/supabase for Studio source) git clone https://github.com//fastabase.git && cd fastabase git submodule update --init # 2. Configure cp config.yaml.example config.yaml # Edit config.yaml with your PlanetScale credentials and email settings # 3. Install pnpm install # 4. Set AWS credentials export AWS_PROFILE=my-profile # or: export AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... AWS_DEFAULT_REGION=us-east-1 # 5. Deploy core stacks (VPC, WAF, DB, Supabase services) pnpm run deploy # default stage = your local username pnpm run deploy --stage prod # named stage # 6. Deploy Supabase Studio (optional, separate stack) pnpm run deploy:cdk:studio # 7. Retrieve outputs aws cloudformation describe-stacks --stack-name Supabase \ --query 'Stacks[0].Outputs' --output table # Key outputs: ApiExternalUrl, SupabasAnonKey # 8. Remove all resources pnpm run remove pnpm run remove --stage prod ``` -------------------------------- ### Deploy Fastabase Instance Source: https://github.com/drizzle-team/fastabase/blob/main/README.md Run the deployment command using pnpm. You can specify a stage name using the `--stage` flag; otherwise, it defaults to your local username. ```shell pnpm run deploy ``` ```shell pnpm run deploy --stage ``` -------------------------------- ### CDK Entry Point (`src/main.ts`) Source: https://context7.com/drizzle-team/fastabase/llms.txt The main CDK entry point synthesizes four stacks: `SupabaseVPC`, `SupabaseWaf`, `SupabaseDB`, and `Supabase`. It reads database credentials from environment variables and upserts them into AWS Secrets Manager. ```typescript // deploy all stacks // Environment variables required: // POSTGRES_HOST, POSTGRES_PORT, POSTGRES_USER, POSTGRES_PASSWORD, // POSTGRES_DB, PLANETSCALE_BRANCH_ID // (optional) POSTGRES_SECRET_NAME import { App } from 'aws-cdk-lib'; import { SupabaseDatabase } from './supabase-db'; import { SupabaseStack } from './supabase-stack'; import { SupabaseVPC } from './supabase-vpc'; import { SupabaseWafStack } from './supabase-waf-stack'; async function main() { // Credentials are upserted into Secrets Manager automatically. // The secret ARN is forwarded to downstream stacks. const app = new App(); const vpcStack = new SupabaseVPC(app, 'SupabaseVPC', { env }); new SupabaseWafStack(app, 'SupabaseWaf', { env: { region: 'us-east-1' } }); const db = new SupabaseDatabase(app, 'SupabaseDB', { env, vpc: vpcStack.vpc, dbSecretArn, }); new SupabaseStack(app, 'Supabase', { env, dbSecretArn, vpc: vpcStack.vpc, db, }); app.synth(); } main().catch(console.error); ``` -------------------------------- ### Initialize Git Submodules Source: https://github.com/drizzle-team/fastabase/blob/main/README.md Run this command to initialize and update all Git submodules after cloning the repository. ```shell git submodule update --init ``` -------------------------------- ### SupabaseVPC Stack Initialization Source: https://context7.com/drizzle-team/fastabase/llms.txt Initializes the `SupabaseVPC` stack, which creates an AWS VPC and establishes peering with PlanetScale's VPC. Required environment variables for PlanetScale connectivity must be set. ```typescript // Required environment variables for SupabaseVPC: // PLANETSCALE_ACCOUNT_ID – PlanetScale AWS account ID // PLANETSCALE_REGION – e.g. "us-east-1" // PLANETSCALE_VPC_ID – PlanetScale VPC ID to peer with // PLANETSCALE_VPC_CIDR – e.g. "10.100.0.0/16" // PLANETSCALE_PEERING_ROLE_ARN – IAM role ARN in PlanetScale account // POSTGRES_PORT – typically 5432 import { SupabaseVPC } from './src/supabase-vpc'; const vpcStack = new SupabaseVPC(app, 'SupabaseVPC', { env }); // Outputs: // VPCId – used by downstream stacks console.log(vpcStack.vpc.vpcId); // vpc-0abc123... ``` -------------------------------- ### Deployment Commands Source: https://context7.com/drizzle-team/fastabase/llms.txt Commands for deploying, deploying to a specific stage, and removing resources using SST. ```shell # Deploy all stacks (uses SST under the hood) export AWS_PROFILE=my-profile pnpm run deploy # Deploy to a named stage (isolates resources in the same account) pnpm run deploy --stage production # Tear down all resources pnpm run remove --stage production ``` -------------------------------- ### Instantiate SupabaseStack Source: https://context7.com/drizzle-team/fastabase/llms.txt Instantiates the SupabaseStack, which provisions core Supabase services including Kong, GoTrue, PostgREST, Realtime, Storage, and Imgproxy. Requires environment variables, VPC, database secret ARN, and the SupabaseDatabase construct. ```typescript import { SupabaseStack } from './src/supabase-stack'; const supabase = new SupabaseStack(app, 'Supabase', { env, dbSecretArn, vpc: vpcStack.vpc, db, }); ``` -------------------------------- ### Instantiate SupabaseDatabase Source: https://context7.com/drizzle-team/fastabase/llms.txt Instantiates the SupabaseDatabase construct, which manages database migrations and user password rotation. Requires environment variables, VPC, and a database secret ARN. ```typescript import { SupabaseDatabase } from './src/supabase-db'; const db = new SupabaseDatabase(app, 'SupabaseDB', { env, vpc: vpcStack.vpc, dbSecretArn: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:/Supabase/user/myuser-AbCdEf', }); ``` -------------------------------- ### Fastabase Configuration (`config.yaml`) Source: https://context7.com/drizzle-team/fastabase/llms.txt This file configures Fastabase settings including dashboard, authentication, email, PlanetScale database credentials, and optional OpenAI API key. Values are read at deployment time. ```yaml # config.yaml dashboard: organizationName: My Organization projectName: My Project auth: disableSignup: false jwtExpiryLimit: 3600 # seconds; max 604800 (1 week) passwordMinLength: 8 email: senderAddress: noreply@example.com senderName: Supabase planetscale: host: aws.connect.psdb.cloud port: 5432 # do NOT use 6432 (PSBouncer) – not all services support it user: my-ps-user password: pscale_pw_xxx database: postgres branchId: br_abc123 openai: apiKey: sk-... # optional ``` -------------------------------- ### Deploy Supabase Studio with SupabaseStudio Source: https://context7.com/drizzle-team/fastabase/llms.txt Deploy Supabase Studio as a serverless Next.js app using cdk-nextjs-standalone. It automatically discovers API URLs and credentials from existing Supabase stacks. ```typescript // src/studio.ts – CDK entry point for Studio (separate from the main stack) // Deploy Studio independently after the core stacks are up: pnpm run deploy:cdk:studio // The entry point auto-discovers outputs from the Supabase and SupabaseVPC stacks: // ApiExternalUrl, DashboardUserSecretArn, AnonKeyParameterName, // ServiceRoleKeyParameterName, VPCId // SupabaseStudio construct accepts: new SupabaseStudio(app, 'Studio', { env, supabaseUrl: 'https://abc123.cloudfront.net', dbPassword: '', anonKey: '', serviceRoleKey: '', vpcId: 'vpc-0abc123...', }); // CloudFormation Output: // StudioUrl – https://.cloudfront.net ``` -------------------------------- ### Set AWS Credentials Source: https://github.com/drizzle-team/fastabase/blob/main/README.md Export your AWS profile to be used for deployment. Refer to AWS documentation for setting up credentials. ```shell export AWS_PROFILE= ``` -------------------------------- ### Configure SupabaseCdn with CacheManager Source: https://context7.com/drizzle-team/fastabase/llms.txt Instantiate SupabaseCdn to create a CloudFront distribution. Add CacheManager for smart CDN cache invalidation via a Lambda Function URL and SQS. ```typescript import { SupabaseCdn } from './src/supabase-cdn'; const cdn = new SupabaseCdn(this, 'Cdn', { origin: loadBalancer, // ALB webAclArn, }); // https://.cloudfront.net const apiUrl = `https://${cdn.distribution.domainName}`; // Attach the Smart CDN cache invalidation pipeline const cacheManager = cdn.addCacheManager(); // cacheManager.url – Lambda Function URL (webhook endpoint for storage-api) // cacheManager.apiKey – Secrets Manager Secret (bearer token) // Storage-api webhook integration (invalidates /storage/v1/object//*) // Set these env vars on the storage container: // WEBHOOK_URL = cacheManager.url // WEBHOOK_API_KEY = // ENABLE_QUEUE_EVENTS = false (use webhook mode) // Cache invalidation webhook payload example: // POST // Authorization: Bearer // { // "event": { // "payload": { // "bucketId": "avatars", // "name": "user-123/avatar.png" // } // } // } // → CloudFront paths invalidated: // /storage/v1/object/avatars/user-123/avatar.png* // /storage/v1/object/sign/avatars/user-123/avatar.png* // /storage/v1/object/public/avatars/user-123/avatar.png* ``` -------------------------------- ### Deploy Auto-Scaling Fargate Service with ECS Patterns Source: https://context7.com/drizzle-team/fastabase/llms.txt Use AutoScalingFargateService to create an ECS Fargate service with auto-scaling, service discovery, and ALB target group support. Configure task image, port, health checks, and environment variables. ```typescript import { AutoScalingFargateService } from './src/ecs-patterns'; // Task size options: none | micro | small | medium | large | xlarge | 2xlarge | 4xlarge // CPU/memory mappings: // micro = 256 vCPU / 512 MB // small = 512 vCPU / 1024 MB // medium = 1024 vCPU / 2048 MB // large = 2048 vCPU / 4096 MB const auth = new AutoScalingFargateService(this, 'Auth', { cluster, taskImageOptions: { image: ecs.ContainerImage.fromRegistry('public.ecr.aws/supabase/gotrue:v2.176.1'), containerPort: 9999, healthCheck: { command: ['CMD', 'wget', '--no-verbose', '--tries=1', '--spider', 'http://localhost:9999/health'], interval: cdk.Duration.seconds(5), timeout: cdk.Duration.seconds(5), retries: 3, }, environment: { GOTRUE_API_HOST: '0.0.0.0', GOTRUE_API_PORT: '9999' }, secrets: { GOTRUE_DB_DATABASE_URL: ecs.Secret.fromSecretsManager(authAdminSecret, 'uri'), GOTRUE_JWT_SECRET: ecs.Secret.fromSecretsManager(jwtSecret), }, }, highAvailability, // CfnCondition – enables auto-scaling when true }); // Internal service endpoint (CloudMap): http://auth.supabase.internal:9999 console.log(auth.endpoint); // Allow Kong to reach Auth kong.connections.allowToDefaultPort(auth); // Register an ALB target group for Kong const targetGroup = kong.addTargetGroup({ healthCheck: { port: '8100', path: '/status', timeout: cdk.Duration.seconds(2) }, }); ``` -------------------------------- ### Database Migration Structure Source: https://context7.com/drizzle-team/fastabase/llms.txt Organizes SQL migrations into two directories: init-scripts for initial schema and migrations for incremental changes. Drizzle ORM tracks applied migrations in separate metadata tables. ```plaintext migrations/ ├── init-scripts/ ← applied first, tracked in drizzle.init-scripts-migrations │ ├── 00000000000000-initial-schema.sql │ ├── 00000000000001-auth-schema.sql │ ├── 00000000000002-storage-schema.sql │ └── 00000000000003-post-setup.sql └── migrations/ ← applied second, tracked in drizzle.migrations ├── 20211115181400_update-auth-permissions.sql ├── 20220317095840_pg_graphql.sql └── ... (40+ incremental Supabase upstream migrations) ``` -------------------------------- ### SupabaseStack CloudFormation Parameters Source: https://context7.com/drizzle-team/fastabase/llms.txt Highlights important CloudFormation parameters for configuring Supabase services, including authentication settings, email sender details, infrastructure options, and container image URIs for overriding default versions. ```typescript // Key CloudFormation parameters (set during `cdk deploy` or via the console): // // Auth: // DisableSignup default: false // SiteUrl default: http://localhost:3000 // RedirectUrls comma-separated allowed redirect origins // JwtExpiryLimit default: 3600 (seconds) // PasswordMinLength default: 8 // // Email: // Email sender address // SenderName default: Supabase // SesRegion default: us-west-2 // EnableWorkMail default: false (creates an awsapps.com test domain) // // Infrastructure: // EnableHighAvailability default: false (enables multi-AZ auto-scaling) // WebAclArn optional WAF web ACL for CloudFront // MinACU / MaxACU Aurora Serverless v2 capacity (unused with PlanetScale) // // Container images (override to pin versions): // AuthImageUri default: public.ecr.aws/supabase/gotrue:v2.176.1 // RestImageUri default: public.ecr.aws/supabase/postgrest:v12.2.12 // StorageImageUri default: public.ecr.aws/supabase/storage-api:v1.24.7 // ImgproxyImageUri default: public.ecr.aws/supabase/imgproxy:v3.8.0 // PostgresMetaImageUri default: public.ecr.aws/supabase/postgres-meta:v0.89.3 // RealtimeImageUri default: public.ecr.aws/supabase/realtime:v2.34.47 ``` -------------------------------- ### Configure External OAuth2 Providers with AuthProvider Source: https://context7.com/drizzle-team/fastabase/llms.txt Use AuthProvider to register external OAuth2 providers for GoTrue. Configuration is managed via CloudFormation parameters and SSM Parameter Store. ```typescript import { AuthProvider } from './src/supabase-auth-provider'; // Providers are added to the Auth service automatically in SupabaseStack: const authProviders = auth.addExternalAuthProviders( `${apiExternalUrl}/auth/v1/callback`, 3, // number of configurable slots ); // Each provider exposes CloudFormation parameters updated post-deploy: // /Auth/Provider1/Name – e.g. GITHUB // /Auth/Provider1/ClientId – OAuth2 client ID // /Auth/Provider1/Secret – OAuth2 client secret (NoEcho) // Update a provider after initial deployment via AWS Console or CLI: // aws cloudformation update-stack \ // --stack-name Supabase \ // --use-previous-template \ // --parameters \ // ParameterKey=AuthProvider1Name,ParameterValue=GITHUB \ // ParameterKey=AuthProvider1ClientId,ParameterValue=Iv1.abc123 \ // ParameterKey=AuthProvider1Secret,ParameterValue=secret_xyz \ // --capabilities CAPABILITY_IAM // Environment variables injected into GoTrue: // GOTRUE_EXTERNAL_GITHUB_ENABLED = true // GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI = https://.../auth/v1/callback // GOTRUE_EXTERNAL_GITHUB_CLIENT_ID = (from SSM) // GOTRUE_EXTERNAL_GITHUB_SECRET = (from SSM) ``` -------------------------------- ### Applying Drizzle Migrations Source: https://context7.com/drizzle-team/fastabase/llms.txt Applies Drizzle ORM migrations using the `migrate` function. Ensure migration files are timestamped and placed in the correct directories. Each migration is applied exactly once. ```typescript // Adding a new migration – create a timestamped .sql file: // migrations/migrations/20250801120000_my_custom_change.sql // The fingerprint of the migrations/ directory is stored in the CloudFormation // resource, so any new file automatically triggers a re-run on the next deploy. // Migration handler logic (cr-migrations-handler.ts): await migrate(db, { migrationsFolder: 'migrations/init-scripts', migrationsTable: 'init-scripts-migrations' }); await migrate(db, { migrationsFolder: 'migrations/migrations', migrationsTable: 'migrations' }); // Each migration file is applied exactly once (idempotent). ``` -------------------------------- ### Supabase Database Migrations Source: https://context7.com/drizzle-team/fastabase/llms.txt The migration handler automatically runs SQL migrations on Create/Update CloudFormation events. It processes migrations in order from `migrations/init-scripts/` followed by `migrations/migrations/`. ```typescript // Migration handler runs automatically on Create/Update CloudFormation events: // 1. migrations/init-scripts/*.sql (tracked in drizzle.init-scripts-migrations) // 2. migrations/migrations/*.sql (tracked in drizzle.migrations) ``` -------------------------------- ### Remove Fastabase Instance Source: https://github.com/drizzle-team/fastabase/blob/main/README.md Run this command to remove a deployed Fastabase instance. If a non-default stage was used during deployment, provide it with the `--stage` flag. ```shell pnpm run remove ``` ```shell pnpm run remove --stage ``` -------------------------------- ### SupabaseStack CloudFormation Outputs Source: https://context7.com/drizzle-team/fastabase/llms.txt Lists key CloudFormation outputs provided by the SupabaseStack, including external API URLs, SSM paths for JWTs, and Secrets Manager ARNs for database credentials. ```typescript // CloudFormation outputs: // ApiExternalUrl – https://.cloudfront.net // AnonKeyParameterName – SSM path to the anon JWT // ServiceRoleKeyParameterName – SSM path to the service_role JWT // DashboardUserSecretArn – Secrets Manager ARN for Studio DB credentials ``` -------------------------------- ### Configure Amazon SES SMTP Credentials with SesSmtp Source: https://context7.com/drizzle-team/fastabase/llms.txt The SesSmtp construct creates an IAM user with SES SendRawEmail permission and generates SMTP credentials stored in Secrets Manager. Optionally deploys Amazon WorkMail. ```typescript import { SesSmtp } from './src/amazon-ses-smtp'; const smtp = new SesSmtp(this, 'Smtp', { region: 'us-west-2', email: 'noreply@example.com', workMailEnabled: workMailEnabled, // CfnCondition }); // Properties resolved at deploy time: smtp.host; // email-smtp.us-west-2.amazonaws.com (or WorkMail host) smtp.port; // 465 smtp.email; // noreply@example.com (or WorkMail address) // Credentials stored in Secrets Manager: // Secret keys: { username, password, host } // Inject into GoTrue: taskDefinition.defaultContainer!.addSecret( 'GOTRUE_SMTP_USER', ecs.Secret.fromSecretsManager(smtp.secret, 'username'), ); taskDefinition.defaultContainer!.addSecret( 'GOTRUE_SMTP_PASS', ecs.Secret.fromSecretsManager(smtp.secret, 'password'), ); ``` -------------------------------- ### Generate Supabase User Password Source: https://context7.com/drizzle-team/fastabase/llms.txt Generates a random password for a database role and stores it in Secrets Manager. The custom resource executes an ALTER USER ... PASSWORD command on the database. The resulting secret contains username, password, and URI. ```typescript // Generate a random password for a DB role and store it in Secrets Manager. // The custom resource runs ALTER USER ... PASSWORD '...' on the database. const authAdminSecret = db.genUserPassword(supabaseStack, 'supabase_auth_admin'); // → Secret ARN: arn:aws:secretsmanager:.../Supabase-SupabaseDB-supabase_auth_admin-... // → Secret JSON keys: { username, password, uri } ``` -------------------------------- ### Generate JWT Secrets and API Keys with JwtSecret Source: https://context7.com/drizzle-team/fastabase/llms.txt Use JwtSecret to provision a custom resource that mints signed JWTs and generates API keys. Store credentials in SSM Parameter Store for consumption by ECS services and Kong. ```typescript import { JwtSecret } from './src/json-web-token'; const jwtSecret = new JwtSecret(this, 'JwtSecret'); // → Secrets Manager: 64-char random secret (no punctuation) // Mint the anon key (safe for client-side use with RLS) const anonKey = jwtSecret.genApiKey('AnonKey', { roleName: 'anon', issuer: 'supabase', expiresIn: '10y', }); // → SSM Parameter: /Supabase/JwtSecret/AnonKey // → JWT payload: { role: 'anon', iss: 'supabase', exp: <10 years> } // Mint the service_role key (server-side only – bypasses RLS) const serviceRoleKey = jwtSecret.genApiKey('ServiceRoleKey', { roleName: 'service_role', issuer: 'supabase', expiresIn: '10y', }); // → SSM Parameter: /Supabase/JwtSecret/ServiceRoleKey // Inject into Kong via ECS secrets taskDefinition.defaultContainer!.addSecret( 'SUPABASE_ANON_KEY', ecs.Secret.fromSsmParameter(anonKey.ssmParameter), ); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.