🚀 Basicrum Local Development
This guide consists of instructions on how to run the full stack of Basicrum locally.
Prerequisites
This project uses mise to manage tool versions (Node.js, pnpm, Biome). Install it first:
# macOS
brew install miseThen activate it in your shell (add to ~/.zshrc or ~/.bashrc):
eval "$(mise activate zsh)"With mise installed, run the following in the project root to install the required tool versions:
mise installThis installs the exact versions of Node.js, pnpm, and Biome defined in mise.toml.
TIP
Install the mise VS Code extension (recommended in .vscode/extensions.json) for automatic IDE integration.
The beacon_service is a Rust project. Install the Rust toolchain via rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shPreparation
Let's build our @basicrum/api_contract local package first.
cd api_contract
pnpm install
pnpm buildNow our frontend and backend will be able to use the package.
You should also run the ClickHouse and Postgres docker containers from the project root:
pnpm start-clickhouse
pnpm start-postgresInstallation
We use pnpm to manage our monorepo
To install all packages, run this in project root directory:
pnpm installTo run the backend from the root directory:
pnpm --filter @basicrum/backend devand similarly for frontend:
pnpm --filter @basicrum/frontend devand the beacon service (this handles the incoming RUM beacons and writes to ClickHouse; the first run needs the GeoIP database, see beacon_service/README.md):
cd beacon_service
./scripts/download-geoip.sh
cargo runThe commands above use pnpm's workspace feature to run the respective commands.
TIP
Just make sure you run the commands from different terminal window
Alternatively, we can also cd into the different folders separately and run pnpm run dev from there to achieve the same.
To install a new package in any of the workspaces, run this command from the root directory:
pnpm --filter @basicrum/frontend add <package_name>TIP
This will install the package in the frontend workspace. To install in the backend workspace, replace frontend with backend in the command above.
Postgres migrations
Postgres
We use postgres to store our non-clickhouse data. The database is manages by Drizzle ORM. Drizzle users the schema files in the src/postgres/schemas folder to manage the database schema. We can then use the following commands to generate the database migrations files. Please run it after you have made changes to the schema files.
pnpm run generate-postgres-migration-filesThis will generate the migration files in the src/postgres/migrations folder. You can then run the following command to apply the migrations.
pnpm run run-postgres-migrationsThis will run the migrations and create the database if it does not exist.
Updating the API contract
To update the API contract, you need to update the src/contract.ts file.
For more information, visit TS-REST website: https://ts-rest.com/docs/intro
After updating the contract, run the following command in the package's root directory:
pnpm buildThen, update the package in the Frontend and Backend projects.
Beacon service (Rust) configuration
All configuration is read from environment variables. Defaults are provided for local development.
| Variable | Default | Description |
|---|---|---|
BEACON_SERVICE_PORT | 3100 | Port to listen on |
CLICKHOUSE_URL | http://localhost:8123 | ClickHouse HTTP URL |
CLICKHOUSE_USER | default | ClickHouse user |
CLICKHOUSE_PASSWORD | local_dev_pass | ClickHouse password |
Beacon service GeoIP database
asset/GeoLite2-City.mmdb is not checked into git. The version to use is pinned in geoip-version — a commit of wp-statistics/GeoLite2-City (which republishes MaxMind's GeoLite2 City database roughly twice a week) plus the sha256 of the download, verified by both the script and the Docker build. Local dev/tests and Docker image builds all download that same pinned version, so builds are reproducible.
./scripts/download-geoip.sh # download the pinned version (no-op if already on disk)
./scripts/download-geoip.sh --check # show the pinned version and newer releases
./scripts/download-geoip.sh --bump # pin the latest release and download it
./scripts/download-geoip.sh --force # re-download the pinned versionTo update the database, run --bump and commit the changed geoip-version file. The Docker build's download layer is cached until the pin changes.
Running the beacon service
Make sure ClickHouse is running (from the project root):
pnpm start-clickhouseThen start the service:
cargo run