Skip to content

About

A directory of websites, apps and tools built with Rust. Itself built with Rust.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

builtwithrust.com

A directory of websites, apps and tools built with Rust. Itself built with Rust.

  • Axum for HTTP, Maud for compile-time-checked HTML, SQLite via sqlx with compile-time-checked SQL.
  • Every public page is rendered once, pre-compressed (brotli/gzip) and served from memory with an ETag. Any catalog write purges the cache.
  • One static binary, embedded assets and migrations. Nothing to install next to it besides the SQLite file (and optionally Litestream for backups).
  • Public submission form with review queue, bearer-token admin JSON API for agents, Stripe-powered "featured" slots, PostHog analytics.

Run it

cp .env.example .env            # set ADMIN_TOKEN at least
export DATABASE_URL=sqlite://data/dev.db?mode=rwc
cargo run -- migrate
cargo run -- seed               # loads seed/projects.json
cargo run                       # http://localhost:3000

Tests: cargo test. Load test: scripts/loadtest.sh (needs oha).

Everything else, including the admin API reference, Stripe and PostHog setup and the rules for changing the code, is in AGENTS.md.

Deployment

Production runs on CapRover at https://builtwithrust.com. Pushes to main run the Rust checks, build an image tagged with the commit SHA in ghcr.io/lvtd-llc/builtwithrust, and deploy it using the app's deployment token. The workflow can also be run manually from main. It waits until /healthz reports the deployed commit in its X-Deployment-Revision header before marking the rollout successful.

GitHub Actions secrets: CAPROVER_SERVER (dashboard origin) and APP_TOKEN (the builtwithrust app token). Image publishing uses GITHUB_TOKEN. CapRover must have permission to pull the image from GHCR.

CapRover settings:

  • Container HTTP port: 3000; one instance pinned to its storage node.
  • Persistent volume builtwithrust-data mounted at /data.
  • SITE_URL=https://builtwithrust.com and a generated ADMIN_TOKEN.
  • DATABASE_URL=sqlite:///data/builtwithrust.db?mode=rwc (the image default).
  • PostHog settings from .env.example; Stripe stays disabled until configured.
  • Custom domain builtwithrust.com, HTTPS enabled, and force HTTPS enabled.

Migrations run automatically at startup. Seed a fresh deployment once with builtwithrust seed inside the running container, then purge the page cache through the admin API. Never seed automatically on deploy: it would overwrite catalog edits. The runtime uses UID 10001, which must own /data.

To roll back, deploy a previous commit's image tag through CapRover. The SQLite volume survives deployments; schema migrations may require a separate database recovery. Persistent storage is not a backup; litestream.yml provides a starting point for configuring backups separately.

License

MIT

IndexNow

The root /{key}.txt route serves indexnow-key.txt as plain text. This is an intentionally public ownership-verification value, not an admin credential. No environment secrets or paid API are required.

The IndexNow Actions workflow checks the public sitemap hourly and after a successful production deployment. It submits new/modified URLs and URLs removed since the last accepted snapshot (including unpublished/deleted projects). Full RFC3339 sitemap timestamps detect same-day listing edits. On any catalog change, all current sitemap URLs are refreshed too: directory/category pages and related-project cards may have changed. Successful deployments force a refresh to cover template/copy changes without database timestamp changes. Unchanged hourly runs make no submissions. GitHub schedules can be delayed.

Snapshots use Actions cache, serialized across runs; they advance only when all batches return HTTP 200 or 202. Errors fail the workflow and the next run retries. An evicted/missing cache bootstraps all current URLs but cannot recover previously removed URLs. Edits made and reverted entirely between polls are not observed. For a missed deletion, submit the removed URL explicitly using the IndexNow API. HTTP 202 means ownership validation is pending; neither 200 nor 202 guarantees indexing. Submission is shared among participating engines, not Google.

Run manually using gh workflow run indexnow.yml, or locally with python scripts/indexnow.py --snapshot /tmp/bwr-indexnow.json. Add --force for a deliberate full refresh. Protocol: https://www.indexnow.org/documentation.

About

A directory of websites, apps and tools built with Rust. Itself built with Rust.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages