A sample notes app for teenybase.
teenybase is in pre-alpha and not suitable for production use yet.
Teenybase is a serverless backend [framework] with a single file configuration and deployment on cloudflare. It includes a sqlite database(d1), file storage(s3/r2), jwt, authentication, custom database access rules(query from frontend), email(mailgun), and more.
This repository is a sample application with teenybase backend and multiple frontend implementation samples. It can be directly cloned and run locally or deployed on cloudflare.
OpenAPI Docs - https://notes-example.teenybase.com/api/v1/doc/ui
Frontend demos
- Hono JSX SSR - https://notes-example.teenybase.com
- Backend in a file - teenybase.ts
- notes table
- Rule based access control
- users table
- Rule based access control
- Username/email + password authentication
- Vitest integration and backend tests
- notes table
- Deploy on cloudflare
- Deploy worker
- Generate schema
- Apply migrations
- Backup database
- Restore database
- Backup bucket
- Restore bucket
- Frontend
- Hono JSX
- Server side rendering (SSR) in worker
- Homepage with public notes list
- Cookie auth
- Email + password
- Login, logout
- Register/Sign up
- Forgot password
- Google Auth
- Apple Auth
- Github Auth
- Discord Auth
- Account notes list
- Create note
- Edit note
- View note
- Pagination
- Full text search
- Account settings
- Hono Client JSX
- React (vite)
- Next.js
- Svelte (vite)
- Hono JSX
- teenybase.ts - Database schema and settings
- wrangler.toml - Cloudflare worker settings
- worker.ts - Worker entry point
- .dev.vars - Development environment variables/secrets
- .prod.vars - Production environment variables/secrets
- migrations - Generated Database migrations and built config. This should be committed to git.
- .local-persist - Local database and bucket storage. This should ideally not be committed to git.
- db_backups - Database backups when doing through cli. Add it to
.gitignore
or justdb_backups/local
if you don't want to commit them. .teeny
and.wrangler
- Temporary folders created by teeny and wrangler. These should not be committed to git.
Clone the repository and install dependencies.
git clone git+ssh://github.com/repalash/teeny-notes-sample.git
cd teeny-notes-sample
npm install
Create .dev.vars
and .prod.vars
files from sample.vars
cp sample.vars .dev.vars
cp sample.vars .prod.vars
Set the values for jwt secrets, admin tokens and other variables in .dev.vars
and .prod.vars
(and make sure they are added to .gitignore
not committed to git). These secrets are referenced in the database settings(teenybase.ts
file) with a $
sign.
Next, Run migrations to create the database with tables.
npm run migrate
Respond with y
to apply the migrations.
The local database is saved as Miniflare
object with sqlite
files in the .local-persist
folder. To reset the local database, simply delete this folder and run npm run migrate
again
Once the database is created, we can execute commands to add data like admin users, restore backups etc. To add a superadmin user -
npm run exec -- users/insert -m post -b '{"values":{"name":"admin","username":"admin","role":"superadmin","email":"admin@example.com","password":"admin123456","passwordConfirm":"admin123456"},"returning":"*"}'
# or teeny exec --local users/insert -m post -b '{"values":{"name":"admin","username":"admin","role":"superadmin","email":"admin@example.com","password":"admin123456","passwordConfirm":"admin123456"},"returning":"*"}'
if
teeny
does not work, usenpx teeny
instead ofteeny
The user can be removed like - teeny exec --local users/delete -m post -b '{"where":"username=\"admin\"","returning":"*"}'
To start the development server, run
npm run dev
# or teeny dev --local
Open the browser and navigate to http://localhost:8787 to see the app.
The OpenAPI docs UI (Swagger) is available at http://localhost:8787/api/v1/doc/ui
Initial Setup -
- Run
wrangler login
and follow steps to login to cloudflare account. This would create a token and save it to the local machine. - Update
wrangler.toml
- set the
name
property. Thename
is the name of the worker in cloudflare. - set the
account_id
(cloudflare account id) property. This can be found in the cloudflare dashboard. - optionally, comment/uncomment
observability
for logging and metrics. - update/remove flags
RESPOND_WITH_ERRORS
andRESPOND_WITH_QUERY_LOG
- set the
- Create the resources like the d1 database and r2 bucket needs to be created in the cloudflare account.
- create D1 Database
wrangler d1 create teeny-notes-sample --location weur
- copy the database name and uid and paste in the
database_name
anddatabase_id
fields(underd1_databases->PRIMARY_DB
) inwrangler.toml
file. - optionally, create another database and copy the database uid for
preview_database_id
field inwrangler.toml
file. This will be used when using--remote
option withdev
- create the bucket
wrangler r2 bucket create teeny-notes-sample --location weur
- copy the bucket name and paste in the
bucket_name
field(underr2_buckets->PRIMARY_R2
) inwrangler.toml
file. DONT change the binding (PRIMARY_R2) - optionally, create another bucket and copy the bucket name for
preview_bucket_name
field inwrangler.toml
file. This will be used when using--remote
option withdev
- Deploy the worker
npm run deploy
This would deploy the worker and set the secrets.
- Copy the deployed route and set it as
API_ROUTE
in.prod.vars
file. This should look likehttps://<worker-name>.<account-name>.workers.dev
unless a different route is set inwrangler.toml
file. This step is required to apply the migrations in the db from next time.
When running in production environment, remove the flags
RESPOND_WITH_ERRORS
andRESPOND_WITH_QUERY_LOG
inwrangler.toml
which are used for debugging in rest api.
The resources can be created in the following locations (as per cloudflare). This is only required for the db and bucket and not the worker as it will be spawned on the edge.
- wnam Western North America
- enam Eastern North America
- weur Western Europe
- eeur Eastern Europe
- apac Asia-Pacific
- oc Oceania
Creation of resources from config will be automated in future versions of teenybase.
Next, deploy the worker to cloudflare.
npm run deploy
# or teeny deploy --migrate --remote
# or teeny migrate --deploy --remote
On first deployment, the worker will be deployed and database migrations will be applied. On subsequent deployments, the migrations will be applied first, and then the worker will be deployed.
teeny deploy
is same asteeny migrate
as it first migrates the database and then deploys the worker. In the examplenpm run deploy
is used, which is same asteeny migrate --remote
.
If this is the first deployment, the secrets will automatically be uploaded from .prod.vars file. Make sure the secrets are set properly in the .prod.vars
file.
Optionally create a superadmin account or insert other data using exec command -
teeny exec --remote users/insert -m post -b '{"values":{"name":"admin","username":"admin","role":"superadmin","email":"admin@example.com","password":"admin123456","passwordConfirm":"admin123456"},"returning":"*"}'
To update the worker with new migrations, or worker changes, simply run the deployment again
npm run deploy
# or teeny deploy --migrate --remote
If there are any migrations required, it will prompt to apply them. Respond with y
to apply the migrations.
The secrets are uploaded automatically when deploying the worker for the first time.
To upload the secrets manually or to update after first deployment, edit the file .prod.vars
and run
teeny secrets upload --remote
Note - If any secret is removed from the
.prod.vars
file and uploaded, it will not be removed from the cloudflare secrets. It will need to be removed manually from the cli or the cloudflare dashboard.
To backup the remote or local database, run
teeny backup --remote
# or teeny backup --local
This will create a backup of the database settings, schema and sql data in the db_backups/[local|remote]
folder.
This will not backup the files in the r2 bucket, that must be done separately. Check the teenybase docs for more details.
To create a worker build, run
npm run build
# or teeny build --local
This is only required for testing, and not for deployment as a worker build is created automatically when deploying.
The database schema, rules and other backend settings are defined as JSON in teenybase.ts.
The settings can be directly edited in the file. After editing the file, migrations needs to be generated and applied to see the effects.
The generated migrations and built settings are stored in the migrations
folder.
This folder is supposed to be committed to version control(git) but files in this folder should not be edited manually.
Any change will be reset the next time migrations are generated.
This folder can be safely deleted, as it will be generated again when running generate
or migrate
.
To validate the database settings and schema, and generate the settings json and migrations, run
npm run generate
# or teeny generate --local
This will compile the teenybase.ts
file and generate migrations/next-config.json
and migrations/xxx_create_table_xxxx.sql
files.
This step is optional and can be skipped as latest migrations are generating every time migrate or deploy is run.
To apply the migrations and update the database with the settings, run
npm run migrate
# or teeny migrate --local
This will first run generate, then apply the un-applied migrations to the database, and also update the migrations/config.json
file with the latest settings from teenybase.ts
file.
The migrations/config.json
file contains the built database settings and schema that the backend uses. This file is imported and used in worker.ts
file.
Sending emails for email verification, password reset etc. is done using the mailgun
service.
An account can be created at mailgun.com which gives 100 emails/day for free on a custom domain.
Once a mailgun account is created, set the details in teenybase.ts
file under email
.
Note - The keys (
MAILGUN_API_KEY
andMAILGUN_WEBHOOK_SIGNING_KEY
) should be set in the.dev.vars
and.prod.vars
files and referenced in theteenybase.ts
file with a$
sign, similar to other secrets.
Optionally, to log mailgun errors and receive them on discord
- add webhooks in mailgun to
https://YOUR_DEPLOYMENT/api/v1/mailgun/webhook/notes-app
for all the events you would like to be notified about. - add a webhook to a discord server(server settings -> Integrations -> webhooks) and add the url/id to
DISCORD_MAILGUN_NOTIFY_WEBHOOK
inteenybase.ts->email->mailgun