- Rust 94%
- TypeScript 4.2%
- HTML 1.2%
- Dockerfile 0.6%
| .githooks | Add pre-commit git hook | |
| backend | Get rid of config table | |
| common | Get rid of config table | |
| frontend | frontend: Handle errors gracefully on /photos/upload | |
| .dockerignore | Build and deploy backend to local docker registry | |
| .gitignore | Initial commit | |
| Cargo.lock | frontend: Init access token from localStorage | |
| Cargo.toml | Initial commit | |
| compose.yaml | backend: Start minio after postgres | |
| Dockerfile | backend: Fix docker build | |
| README.md | Add pre-commit git hook | |
| rust-analyzer.toml | Add rustfmt and rust-analyzer configs | |
| rustfmt.toml | Add rustfmt and rust-analyzer configs | |
Crowdmapper
Crowdmapper is a Rusty take on self-hosted crowdmapping 🦀🚀
The frontend is written with reactive Leptos using client-side rendering and Trunk as build tool.
The backend is written with axum to drive HTTP, and optionally both sqlx (currently only with postgres support) and minio for persistent data and file storage respectively.
Building from source
Requirements
- Rust nightly (tested on
1.95.0-nightly) - Trunk (tested on
v0.21.14, installation guide)
Frontend
To build the frontend, use trunk build:
trunk build --config frontend/Trunk.toml
This outputs all necessary assets to serve the frontend statically in
frontend/dist/.
Backend
The backend can simply be built with cargo build:
cargo build -p backend
However, this only includes a memory store. For persistent storage, enable the
postgres feature with:
cargo build -p backend -F postgres
Development
Requirements
- Docker
- Docker Compose
- watchexec (tested on
v2.3.2, installation guide)
Frontend
Use trunk to serve a development server (handles livereload and API proxying for
you) with:
trunk serve --config frontend/Trunk.toml
Which can be viewed at http://localhost:8080/.
Backend
Use watchexec to watch the backend/
directory for changes to .rs and .toml files with:
CROWDMAPPER_JWT_SECRET=abc watchexec -r -w backend -e rs,toml -- cargo run -p backend
Note
The
CROWDMAPPER_JWT_SECRETenvironment variable is required as a security measure.
The backend only ships with support for a memory store by default. To enable
persistence, it may be run with the postgres feature:
CROWDMAPPER_JWT_SECRET=abc watchexec -r -w backend -e rs,toml -- cargo run -p backend -F postgres
Integration
Backend
To test and verify that the persistence works correctly, you can easily deploy a development data-/object-store with:
docker compose up
This will expose a PostgreSQL instance on localhost:5432 and a MinIO instance
on localhost:9000 (and a corresponding admin console on
http://localhost:9001).
Once both of these are running, you can start developing with:
CROWDMAPPER_DATABASE_URL=postgres://crowdmapper:crowdmapper@localhost:5432/crowdmapper CROWDMAPPER_JWT_SECRET=abc watchexec -r -w backend -e rs,toml -- cargo run -p backend -F postgres
The minio-init service of compose.yaml will create a photos bucket for you
in the minio container. The first time you run the backend, sqlx will
migrate the postgres tables.
The default username and password for both minio and postgres is
crowdmapper. To access these directly from your terminal, you can use the
terminal-based psql utility with:
psql postgres://crowdmapper:crowdmapper@localhost:5432/crowdmapper
And MinIO Client (mc) with:
$ mc alias set crowdmapper http://localhost:9000 crowdmapper crowdmapper
$ mc ls bs crowdmapper
[2026年02月04日 22:21:14 CET] 0B photos/
Frontend
To initialize the access token context of the frontend with access to
http://localhost:8080/photos and the ability
to upload new ones at
http://localhost:8080/photos/upload,
you can pass TRUNK_CROWDMAPPER_INIT_ACCESS_TOKEN as an environment variable
to trunk serve like so:
TRUNK_CROWDMAPPER_INIT_ACCESS_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxYmVlYzU3ZS0xNTcwLTQ2MWEtYjhkOS03OTcwZDRjZGM1ODQiLCJwaG8iOjE1LCJleHAiOjQxMDI0NDEyMDB9._TOtEzIyJe7a11dmPLr1ZwTfV3HTyuqsL5dtEiK2zaQ trunk serve --config=./frontend/Trunk.toml
This works because the JWT has the following claims:
{
"sub": "1beec57e-1570-461a-b8d9-7970d4cdc584",
"pho": 15,
"exp": 4102441200
}
and is signed with the same JWT secret as is passed to the backend with CROWDMAPPER_JWT_SECRET.
Git Hooks
It is recommended that you run:
git config --local core.hooksPath .githooks/
after cloning. This will run .githooks/pre-commit prior to each commit which
will check formatting, and run linting and tests for all features. You need to
install leptosfmt for this to work.