No description
  • Python 42%
  • Svelte 24%
  • CSS 23.9%
  • TypeScript 6.9%
  • Just 1.9%
  • Other 1.2%
Find a file
2026-08-08 21:25:54 +00:00
apps Initial commit. 2026-08-08 21:25:54 +00:00
data/fixtures Initial commit. 2026-08-08 21:25:54 +00:00
docs/dev-docs Initial commit. 2026-08-08 21:25:54 +00:00
example-data Initial commit. 2026-08-08 21:25:54 +00:00
examples Initial commit. 2026-08-08 21:25:54 +00:00
infra Initial commit. 2026-08-08 21:25:54 +00:00
.dockerignore Initial commit. 2026-08-08 21:25:54 +00:00
.gitignore Initial commit. 2026-08-08 21:25:54 +00:00
AGENTS.md Initial commit. 2026-08-08 21:25:54 +00:00
docker-entrypoint.sh Initial commit. 2026-08-08 21:25:54 +00:00
Dockerfile Initial commit. 2026-08-08 21:25:54 +00:00
justfile Initial commit. 2026-08-08 21:25:54 +00:00
package.json Initial commit. 2026-08-08 21:25:54 +00:00
plan.md Initial commit. 2026-08-08 21:25:54 +00:00
pnpm-lock.yaml Initial commit. 2026-08-08 21:25:54 +00:00
pnpm-workspace.yaml Initial commit. 2026-08-08 21:25:54 +00:00
README.md Initial commit. 2026-08-08 21:25:54 +00:00
todo.md Initial commit. 2026-08-08 21:25:54 +00:00

Open Climbing

Open Climbing is an open-source, open-data platform for discovering climbing areas, browsing routes, and viewing interactive photographic topos. It is designed as a mobile-first web application with explicit offline area downloads.

The project is in early development. The backend catalog API and first mobile-first browsing interface are implemented.

Planned features

  • Area and sector discovery
  • Route browsing with grade and discipline filters
  • Interactive photographic topos
  • Map-based search
  • Image licensing and attribution
  • Offline area downloads
  • Curated open-data imports

See plan.md for the architecture, milestones, and complete MVP scope. Technical notes are indexed under docs/dev-docs/.

Deploy with Coolify

The root Dockerfile builds the SvelteKit frontend and FastAPI backend into one production image. In Coolify, create a Dockerfile application with port 8000, health check path /health, and this required runtime variable:

BASE_URL=https://dev.climbs.example.com
OPEN_CLIMBING_DATABASE_URL=postgresql+psycopg://user:password@host:5432/database
OPEN_CLIMBING_ENVIRONMENT=development

Deploy develop to the development environment and main to production. BASE_URL supplies the public origin; its hostname is allowed automatically alongside localhost and 127.0.0.1, so a separate allowed-hosts variable is not needed. The container waits up to 60 seconds for PostgreSQL and applies Alembic migrations before accepting traffic. OPEN_CLIMBING_SECRET_KEY is not required until authentication or signed sessions are implemented. See docs/dev-docs/coolify.md for the complete environment isolation, branch, backup, and promotion strategy.

Coolify-generated postgres:// and postgresql:// connection strings are accepted and normalized to the psycopg driver automatically. Keep database credentials available at runtime only; do not expose them as Docker build variables.

The footer displays the release version from the root package.json and the first eight characters of the deployed commit. Enable Include Source Commit in Build in Coolify so its predefined SOURCE_COMMIT build argument is embedded in the static frontend. Local Docker builds add the current Git commit automatically.

Test the production image locally with an isolated PostGIS container:

just docker-local-up
just docker-local-health
just docker-local-logs
just docker-local-down

The local recipes use sudo docker by default and publish the application at http://localhost:8811. Set DOCKER=docker when the current user already has Docker socket access.

Technology

Backend

  • Python
  • FastAPI
  • SQLAlchemy 2
  • Alembic
  • PostgreSQL with PostGIS
  • Pydantic
  • uv, pytest, Ruff, and ty

Frontend

  • SvelteKit and Svelte 5
  • TypeScript
  • Tailwind CSS and shadcn-svelte
  • MapLibre GL JS
  • IndexedDB and service workers

Repository layout

apps/api/                 FastAPI application and tests
apps/web/                 SvelteKit catalog frontend
infra/compose.yaml        Local PostgreSQL/PostGIS and API services
justfile                  Development commands
plan.md                   Product and implementation plan
docs/dev-docs/           Technical and deployment documentation

Getting started

Prerequisites

  • Docker with Docker Compose
  • uv for local backend development
  • pnpm for frontend development
  • just for the convenience commands (optional)

Run with Docker Compose

docker compose -f infra/compose.yaml up --build

In another terminal, apply the database migration:

cd apps/api
uv run alembic upgrade head

The API is available at:

Using just, the equivalent commands are:

just infra-up
just api-migrate

Run the API locally

Start PostgreSQL first:

docker compose -f infra/compose.yaml up -d postgres

Then install dependencies, migrate, and launch FastAPI:

cd apps/api
uv sync --dev
uv run alembic upgrade head
uv run fastapi dev src/open_climbing_api/main.py

Configuration uses environment variables prefixed with OPEN_CLIMBING_. The default database URL connects to the local Compose PostgreSQL service exposed on port 5432.

Run the frontend locally

With the API running on port 8000:

pnpm install
cp apps/web/.env.example apps/web/.env
pnpm --dir apps/web dev

The web application is available at http://localhost:5173 and listens on all interfaces for LAN or Tailscale access. Set API_PROXY_TARGET in apps/web/.env if the API uses another port.

For a single-origin build, run just web-build and restart FastAPI. FastAPI will serve the generated frontend at / while retaining the API under /api/v1.

Run an isolated branch preview

The development Compose stack is separate from the default catalog stack. It uses its own PostGIS volume, exposes PostgreSQL on port 5433, migrates and loads the sample catalog automatically, and serves the production frontend and API from the same origin on port 8125.

just dev-infra-up

Open http://localhost:8125. Follow startup with just dev-infra-logs, stop it with just dev-infra-down, or remove its database volume with just dev-infra-reset.

Override the host ports when needed:

OPEN_CLIMBING_DEV_PORT=9125 OPEN_CLIMBING_DEV_DB_PORT=6433 just dev-infra-up

Apple containers on macOS

On Apple silicon with macOS 26 or newer, the same isolated preview can run with Apple's container CLI instead of Docker. The recipe starts the container system when necessary and creates a dedicated network, PostGIS volume, database container, and API container.

just mac-dev-infra-up
just mac-dev-infra-logs

Stop the containers with just mac-dev-infra-down. Use just mac-dev-infra-reset to also delete the development database volume and network. OPEN_CLIMBING_DEV_PORT and OPEN_CLIMBING_DEV_DB_PORT provide the same host-port overrides as the Docker recipe.

Development commands

just api-dev       # Run the development API
just api-test      # Run backend tests
just api-lint      # Run Ruff checks
just api-format    # Format backend code
just api-migrate   # Apply Alembic migrations
just web-dev       # Run the SvelteKit frontend on all interfaces
just web-build     # Build the frontend for FastAPI to serve
just web-check     # Check, test, and build the frontend
just infra-up       # Start local services
just infra-down     # Stop local services
just dev-infra-up   # Build and run an isolated preview on port 8125
just dev-infra-logs # Follow the branch preview API logs
just dev-infra-down # Stop the isolated branch preview
just dev-infra-reset # Stop it and delete its development database
just mac-dev-infra-up # Run the preview with Apple's container CLI
just mac-dev-infra-logs # Follow the Apple container API logs
just mac-dev-infra-down # Stop the Apple containers
just mac-dev-infra-reset # Stop them and delete the development database

Without just, run the corresponding uv commands from apps/api.

Quality checks

cd apps/api
uv run ruff check .
uv run ruff format --check .
uv run ty check src tests
uv run pytest

Current application

The frontend currently supports area discovery, crag details, sector selection, and route name/grade filtering. It consumes the typed catalog resources under /api/v1, including regions, countries, crags, sectors, and routes.

Contributing

The contribution workflow is still being established. For now, open an issue or submit a focused pull request that includes tests and passes the quality checks above.