flowingkhaosSign in
Deploy your own Travolestep 5 of 7 · 0 of 14 carriedSign in to keep it
Step 5 of 7 · weight 3 · about 40 minutes

Provision Neon, R2 and Better Auth

1. The database — Neon

  1. Create a Neon project. Pick the region nearest to where you will deploy.
  2. Copy the pooled connection string. It starts with postgresql:// and ends with ?sslmode=require.
  3. Put it in .env as DATABASE_URL.

Create the tables, then the reference data:

bun run db:migrate
bun run db:seed

The seed can run as often as you like. It inserts six categories and the 230 countries, and it never duplicates a row.

2. Receipt storage — Cloudflare R2

  1. In Cloudflare, open R2 and create a bucket, for example travole-receipts. Keep it private.
  2. Create an R2 API token with Object Read & Write on that bucket.
  3. Cloudflare shows the token’s credentials once. Copy them now.

Two traps here, both seen in real installs:

  • R2_ACCESS_KEY_ID is the token’s Access Key ID — 32 hexadecimal characters. It is not the long token value. With the wrong one, every call fails with Credential access key has length 53, should be 32.
  • A read-only token lists the bucket fine and then refuses every upload with 403 AccessDenied. Check the permission before you debug the code.
R2_ACCOUNT_ID=<your Cloudflare account id>
R2_ACCESS_KEY_ID=<32 hex characters>
R2_SECRET_ACCESS_KEY=<the secret shown with it>
R2_BUCKET=travole-receipts

3. Authentication — Better Auth

Better Auth needs a secret to sign sessions. Generate one:

openssl rand -base64 32
BETTER_AUTH_SECRET=<the output>
BETTER_AUTH_URL=http://localhost:3000

4. Who may create an account

Travole is closed by default. The first account is created through a bootstrap door, and that door closes by itself the moment it is used. Everyone after that needs an invitation.

AUTH_ALLOW_FIRST_USER=true
AUTH_ALLOW_SIGNUP=false
AUTH_ALLOW_INVITATIONS=true
AUTH_ALLOWED_EMAIL=<your email>

Only the exact string true means true. 1, yes and TRUE all mean false. A lenient parser would turn a typo into an open registration page.

5. Check it locally

bun run dev

Open http://localhost:3000/signup and create your account with the address you put in AUTH_ALLOWED_EMAIL. You are now the admin. Create a trip, add one expense with a PDF receipt, and download it again. If all three work, every service is wired correctly.

The gate · a reading check closes this stepweight 3 of Σw 14

Check what you read in “Provision Neon, R2 and Better Auth”

The questions are public; scoring them needs an account. They were generated once for this step, and the key never leaves the server.

Loading the check…

All 7 stepsGo to the gate

Luke Sidney writes and builds everything here, alone, in the open. lukesidney.me