Skip to content

Setup and Deployment

Set up Allowealth locally and deploy it to production.

Set up your local environment to run the application and documentation.

  • Bun
  • Git
  • Optional: Playwright dependencies for end-to-end tests
Terminal window
cp .env.example .env
./scripts/setup.sh

At minimum, set these auth-related values in your local .env before testing sign-in:

Terminal window
PUBLIC_URL=http://localhost:4321
BETTER_AUTH_SECRET=replace-with-a-random-secret
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
Terminal window
bun run dev
bun run docs:dev
  • App: Runs the Astro server from the project root.
  • Docs: Runs the Starlight server from apps/docs.

Always run quality gates before you push code.

Terminal window
bun run lint:fix
bun run stylelint:fix
bun run format:fix
bun run typecheck
Terminal window
bun run test
bun run test:e2e

Allowealth supports multiple deployment targets. Use the DEPLOY_TARGET environment variable to select the appropriate Astro adapter at build time.

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.

Create the D1 database:

Terminal window
wrangler d1 create allowealth-db

Copy wrangler.toml.example to wrangler.toml and add your database ID:

[[d1_databases]]
binding = "DB"
database_name = "allowealth-db"
database_id = "<your-database-id>"

D1 does not use DATABASE_URL. Set the application secrets instead:

Terminal window
wrangler secret put EMAIL_API_KEY
wrangler secret put BETTER_AUTH_SECRET
wrangler secret put GOOGLE_CLIENT_ID
wrangler secret put GOOGLE_CLIENT_SECRET
wrangler secret put PUBLIC_URL

Apply SQLite migrations to the remote D1 database, then deploy:

Terminal window
for file in drizzle/sqlite/*.sql; do
wrangler d1 execute allowealth-db --remote --file="$file"
done
bun run deploy:cloudflare

After the Better Auth migration, the first deployment forces a one-time logout because legacy sessions are not preserved.

Use the CLI against remote D1:

Terminal window
bun run aw workspace create --target d1 --name "My Family" --email admin@example.com

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 },
]
  • “Cannot perform I/O on behalf of a different request”: The database middleware must call prepareForRequest() to reset connections per request.
  • “D1_ENABLED is set but D1 binding is not available”: Uncomment the [[d1_databases]] section in wrangler.toml and verify the database ID.
  • import.meta.env.DATABASE_URL is undefined: Use getEnv('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/google and that PUBLIC_URL matches the deployed origin exactly.