Setup and Deployment
Set up Allowealth locally and deploy it to production.
Local Development
Section titled “Local Development”Set up your local environment to run the application and documentation.
Prerequisites
Section titled “Prerequisites”- Bun
- Git
- Optional: Playwright dependencies for end-to-end tests
1. Install and Bootstrap
Section titled “1. Install and Bootstrap”cp .env.example .env./scripts/setup.shAt minimum, set these auth-related values in your local .env before testing sign-in:
PUBLIC_URL=http://localhost:4321BETTER_AUTH_SECRET=replace-with-a-random-secretGOOGLE_CLIENT_ID=GOOGLE_CLIENT_SECRET=2. Start Application and Docs
Section titled “2. Start Application and Docs”bun run devbun run docs:dev- App: Runs the Astro server from the project root.
- Docs: Runs the Starlight server from
apps/docs.
3. Run Quality Gates
Section titled “3. Run Quality Gates”Always run quality gates before you push code.
bun run lint:fixbun run stylelint:fixbun run format:fixbun run typecheck4. Verify Tests
Section titled “4. Verify Tests”bun run testbun run test:e2eDeployment
Section titled “Deployment”Allowealth supports multiple deployment targets. Use the DEPLOY_TARGET environment variable to select the appropriate Astro adapter at build time.
Cloudflare Workers
Section titled “Cloudflare Workers”Allowealth runs on Cloudflare Workers at the edge using the @astrojs/cloudflare adapter.
Use Cloudflare D1 for the production database. It runs SQLite-compatible storage at the edge and matches the local schema.
1. Configure D1
Section titled “1. Configure D1”Create the D1 database:
wrangler d1 create allowealth-dbCopy wrangler.toml.example to wrangler.toml and add your database ID:
[[d1_databases]]binding = "DB"database_name = "allowealth-db"database_id = "<your-database-id>"2. Set secrets
Section titled “2. Set secrets”D1 does not use DATABASE_URL. Set the application secrets instead:
wrangler secret put EMAIL_API_KEYwrangler secret put BETTER_AUTH_SECRETwrangler secret put GOOGLE_CLIENT_IDwrangler secret put GOOGLE_CLIENT_SECRETwrangler secret put PUBLIC_URL3. Migrate and deploy
Section titled “3. Migrate and deploy”Apply SQLite migrations to the remote D1 database, then deploy:
for file in drizzle/sqlite/*.sql; do wrangler d1 execute allowealth-db --remote --file="$file"done
bun run deploy:cloudflareAfter the Better Auth migration, the first deployment forces a one-time logout because legacy sessions are not preserved.
4. Create the first workspace
Section titled “4. Create the first workspace”Use the CLI against remote D1:
bun run aw workspace create --target d1 --name "My Family" --email admin@example.comCI/CD and Custom Domains (Cloudflare)
Section titled “CI/CD and Custom Domains (Cloudflare)”The GitHub Actions workflow (.github/workflows/deploy-cloudflare.yml) deploys automatically when you push to the release branch or create version tags. Set CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID in your GitHub repository secrets.
To use a custom domain, add it to your Cloudflare account and update the routes pattern in wrangler.toml:
routes = [ { pattern = "allowealth.io", custom_domain = true },]Troubleshooting
Section titled “Troubleshooting”- “Cannot perform I/O on behalf of a different request”: The
databasemiddleware must callprepareForRequest()to reset connections per request. - “D1_ENABLED is set but D1 binding is not available”: Uncomment the
[[d1_databases]]section inwrangler.tomland verify the database ID. import.meta.env.DATABASE_URLis undefined: UsegetEnv('DATABASE_URL')to read from the runtime environment instead of the build-time environment.- Google OAuth callback fails: Verify Google is configured with
/api/auth/callback/googleand thatPUBLIC_URLmatches the deployed origin exactly.