Skip to content

jo-m/cartomancer

Repository files navigation

Cartomancer logo

Cartomancer

The gpx track library with a touch of magic.

There are a bazillion route planning and activity tracking apps, but none of them is good at managing a library of existing tracks1. This one tries to be.

Features

  • Live weather forecasts and road closures (Switzerland only).
  • Filtering, search, tagging, mark favorites.
  • Automatic reverse geocoding of tracks for search.
  • Map view: SwissTopo.
  • Does not use any 3rd party live APIs. Instead, will download data in the background and query that locally (meteo and geo names).
  • Easy to self host, single binary, SQLite only.

Deployment (Docker)

See releases. The app runs as root inside the container, it is advised to use rootless Podman/Docker. To deploy without Docker, you need to build the binary yourself (see below). For all configuration options, see OPTIONS.md. On startup, forecast files and the geonames database will be downloaded and indexed, which will keep the CPU busy for a while.

The absolute minimum for a production deployment:

# JSONline logs, for human readable set true.
export LOG_PRETTY=false
# Create an initial admin account.
# Use setpass subcommand to set the password later.
export APP_INIT_ADMIN_EMAIL=admin@example.com
# Set to true to allow users self registration.
export APP_REGISTRATION_ENABLED=false
# Those should be persisted, otherwise sessions are lost between restarts.
export SESSION_JWT_SECRET=$(docker run ghcr.io/jo-m/cartomancer:latest genjwtsecret)
export APP_EMAIL_JWT_SECRET=$(docker run ghcr.io/jo-m/cartomancer:latest genjwtsecret)
# You may also want to configure email sending (MAIL_...).

# Run with bind mount.
mkdir -p data
docker run -it --rm                            \
  -p 8080:8080                                 \
  --mount "type=bind,src=$PWD/data,dst=/data"  \
  --env LOG_PRETTY                             \
  --env APP_INIT_ADMIN_EMAIL                   \
  --env APP_REGISTRATION_ENABLED               \
  --env SESSION_JWT_SECRET                     \
  --env APP_EMAIL_JWT_SECRET                   \
  ghcr.io/jo-m/cartomancer:latest

# To reset the admin password (adapt mount if using bind mount):
docker run -it --rm                            \
  --mount "type=bind,src=$PWD/data,dst=/data"  \
  ghcr.io/jo-m/cartomancer:latest              \
  --log-pretty                                 \
  setpass admin@example.com

To terminate TLS, run behind a reverse proxy. It is a good idea to ratelimit the /api/sessions/login endpoint.

Development

All build and dev tools are provided via a Nix flake. Install Nix, direnv and nix-direnv so entering the repo automatically loads the shell and .envrc dev config.

# Starts the backend, with auto reload
go tool air

# In a separate shell, start the frontend
cd frontend/
npm install
npm run dev
# See internal/pkg/app/config.go for login.
open http://localhost:5173

Git hooks

Hooks provided in .githooks/:

  • commit-msg: enforces component: message or comp1/comp2: message subjects.
  • pre-push: rejects pushes containing fixup!/squash! commits.

Install once after cloning:

git config core.hooksPath .githooks

Commands

# See Makefile for more.
make gen
make test
make test_online
make check

# Migrations
go tool goose status
go tool goose create REPLACEME sql
go tool goose up
go tool goose validate

# SQL queries
go tool sqlc generate
go tool sqlc vet --file internal/pkg/db/sqlc.yaml

# View Go docs
go run golang.org/x/pkgsite/cmd/pkgsite@latest -open -http localhost:8081
open http://localhost:8081/jo-m.ch/go/cartomancer

Email

# Run the mock email server (in a separate shell)
go tool MailHog
open http://127.0.0.1:8025/

Profiling (pprof)

The server includes a built-in pprof debug server, disabled by default. Enable it by setting a listen address:

export PPROF_ADDR=localhost:6060

Usage with go tool pprof:

# Heap profile (current allocations)
go tool pprof http://localhost:6060/debug/pprof/heap
# Heap profile (total allocations since start, useful for finding hot paths)
go tool pprof -alloc_space http://localhost:6060/debug/pprof/heap
# 30-second CPU profile
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30

Inside the pprof interactive shell, useful commands are top, list <func>, and web (opens a SVG graph in the browser).

Build

The compiled frontend assets are embedded directly into the binary. Reproducible builds are provided by the Nix flake:

# Build the binary (result/bin/cartomancer)
nix build

# Build just the frontend static assets
nix build .#frontend

# Build a minimal Docker/OCI container image as a tar.gz
nix build .#dockerImage
docker load < image.tar.gz

# Cross-compile to aarch64-linux from x86_64-linux
nix build .#packages.aarch64-linux.cartomancer
nix build .#packages.aarch64-linux.dockerImage

Creating releases

  1. Go to the GitHub Releases page and click Draft a new release.
  2. Create a new tag (e.g. v1.2.0).
  3. Fill in the release title and description, then click Publish release.
  4. The Release workflow will automatically build Docker images and publish a source archive to the release.

Footnotes

  1. There is https://wanderer.to/, which is quite nice. But it has many features I don't need, and is missing some I want. ↩

About

The gpx track library with a touch of magic. 🪄

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors