Operations

Self-host

Draai je eigen routess-instantie met Docker Compose.

Deze handleiding krijgt een routess-instantie op je eigen machine of server draaiend in ongeveer vijf minuten. Voor Kubernetes, zie Kubernetes.

Wat je nodig hebt

  • Docker en Docker Compose v2 (een moderne Docker Desktop of Docker Engine komt met allebei).
  • Een Google OAuth-client voor Google-aanmelding (het compose-bestand vereist het). Gebruikers kunnen ook met e-mail + wachtwoord aanmelden zodra de stack draait.
  • Een Mapbox access token; de gratis tier volstaat.
  • Een Valhalla-routing-engine (VALHALLA_URL). Routeberekening en wegdekanalyse lopen erlangs; zonder geven de routing-endpoints 503 terug.
  • Lange willekeurige strings voor JWT_SECRET, ANALYTICS_SALT, PAT_PEPPER en DB_PASSWORD. Genereer ze met openssl rand -base64 32.

Optioneel, netjes uitgeschakeld wanneer niet gezet:

  • Resend voor transactionele e-mail (zonder dit worden verificatie-URL's naar stdout gelogd).
  • Sentry / GlitchTip voor het rapporteren van browserfouten.
  • Umami voor productanalytics.
  • Adminrol voor toegang tot het ingebouwde adminpaneel.

Google OAuth instellen

  1. Open de credentials-pagina van de Google Cloud Console.
  2. Maak een OAuth 2.0 Client ID van het type Web application.
  3. Voeg onder Authorized JavaScript origins de URL toe die je gebruikers openen (bv. http://localhost:8080 of https://routess.example.com).
  4. Voeg onder Authorized redirect URIs <your-web-url>/auth/callback toe.
  5. Kopieer de Client ID en het Client secret.

Een Mapbox-token ophalen

  1. Meld je aan op account.mapbox.com.
  2. Maak een public access token (pk.…) onder Access tokens.
  3. Beperk het tot je domein wanneer je naar productie gaat.

Draaien

git clone https://github.com/robbeverhelst/routess.git
cd routess
cp docker/.env.selfhost.example .env
# edit .env and fill in the required values
docker compose -f docker/compose.selfhost.yaml --project-directory . up -d

Open daarna http://localhost:8080.

De stack start vier containers:

ServiceImageStandaardpoort
Postgrespostgres:18(intern)
APIghcr.io/robbeverhelst/routess-api3000
Webghcr.io/robbeverhelst/routess-web8080
Docsghcr.io/robbeverhelst/routess-docs3002

Wijzig de host-poorten via WEB_PORT, API_PORT, DOCS_PORT in .env.

Een versie pinnen

De standaardtag is latest. Pin voor productie naar een specifieke release:

ROUTESS_TAG=1.122.7 docker compose -f docker/compose.selfhost.yaml --project-directory . up -d

Of zet ROUTESS_TAG in .env. Zie de releases-pagina voor de beschikbare tags.

Omgevingsvariabelen

Het .env-bestand in docker/.env.selfhost.example is de bron van waarheid. De variabelen die je het vaakst aanraakt:

VariabeleVereistStandaardDoel
JWT_SECRETja-Tekent sessie- en API-tokens. Roteren logt iedereen uit.
ANALYTICS_SALTja-Hasht user-ID's in analytics-events. Roteren reset de analytics-pseudoniemen.
PAT_PEPPERja-Hasht personal access tokens in rust. Roteren maakt elke bestaande PAT ongeldig.
DB_PASSWORDja-Postgres-wachtwoord.
GOOGLE_CLIENT_ID/SECRETja-Google OAuth-credentials.
VITE_MAPBOX_ACCESS_TOKENja-Mapbox access token gebruikt door de webapp.
PUBLIC_WEB_URLneehttp://localhost:8080Waar gebruikers de app openen. Gebruikt als OAuth-redirect-basis.
PUBLIC_API_URLneehttp://localhost:3000Waar de webapp de API bereikt.
ADMIN_EMAILSneeleegKommagescheiden e-mailadressen die bij login de adminrol krijgen. Leeg schakelt het adminpaneel uit.
RESEND_API_KEYneeleegResend API-key. Leeg valt terug op het loggen van verificatie-URL's naar stdout.
EMAIL_FROMneeroutess <[email protected]>Afzenderadres gebruikt door Resend.
VALHALLA_URLjaleegBase-URL van een self-hosted Valhalla-instantie voor routing en wegdekanalyse. Leeg geven de routing-endpoints 503 terug.
VITE_UMAMI_URL / _WEBSITE_IDneeleegUmami-endpoint en site-ID voor de webapp. Leeg schakelt productanalytics uit.
UMAMI_URL / _WEBSITE_IDneeleegHetzelfde Umami-endpoint en site-ID voor de docs-site (Next leest ze aan serverzijde).
VITE_SENTRY_DSNneeleegSentry / GlitchTip DSN voor het rapporteren van browserfouten.
VITE_SENTRY_ENVIRONMENTneeproductionOmgevingslabel dat aan browserfoutrapporten wordt gehangen.
PUBLIC_DOCS_URLneehttp://localhost:3002Canonieke origin van de docs-site, gebruikt in zijn sitemap-, robots.txt- en llms.txt-links.

Geavanceerde variabelen

De API begrijpt meer knoppen dan het compose-bestand doorgeeft. Om er een te gebruiken, voeg je hem toe onder de environment van de api-service in docker/compose.selfhost.yaml (of je eigen override-bestand):

VariabeleStandaardDoel
LOG_LEVELinfoPino-loglevel voor de API (debug, info, warn, error).
SESSION_TTL_DAYS7Hoe lang een browsersessie geldig blijft.
SESSION_COOKIE_NAMEroutess_sessionNaam van de HTTP-only sessiecookie.
JWT_EXPIRES_IN7dLevensduur van het JWT-token.
FRONTEND_URLSleegKomma- of newline-gescheiden lijst van toegestane web-origins; overschrijft FRONTEND_URL indien gezet.
SWAGGER_ENABLEDfalse in prodServeert interactieve API-docs op SWAGGER_PATH.
SWAGGER_PATH/apiPad voor de Swagger UI wanneer ingeschakeld.
TELEMETRY_ENABLEDtrueHoofdschakelaar voor OpenTelemetry (metrics + traces).
METRICS_ENABLEDtruePrometheus-metrics op /metrics op de API-poort. Geeft 503 wanneer uitgeschakeld.
OTEL_EXPORTER_OTLP_ENDPOINTleegOTLP-collector base-URL voor traces (/v1/traces wordt aangevuld). Leeg schakelt trace-export uit.
OTEL_EXPORTER_OTLP_HEADERSleegExtra OTLP-headers als JSON-object, bv. {"authorization":"Bearer …"}.
GRAFANA_URLSleegJSON-object met dashboardlinks die in het adminpaneel worden getoond: {"apiOverview":"…","apiLatency":"…","runtime":"…"}.

Voor de web-container:

VariabeleStandaardDoel
VITE_SENTRY_TRACES_SAMPLE_RATE0.1Fractie van browsersessies die getraced wordt wanneer Sentry is ingeschakeld.
VITE_SENTRY_DEBUGfalseUitgebreide logging van de Sentry SDK.

Console-logging in de browser staat standaard op warn. Om één browser te debuggen, zet je localStorage["routess:log-level"] op debug, info, warn, error of none en herlaad je.

Betalingen (alleen het gehoste product)

Routess.com verkoopt een Pro-jaarpas (ADR 0039). Een zelf gehoste installatie laat betalingen uit, wat de standaard is: elke functie blijft ontgrendeld, iedereen krijgt GENERATION_QUOTA_PER_DAY gegenereerde routes per dag, en er wordt geen betaalprovider gecontacteerd. Laat BILLING_ENABLED=false staan, of zet het niet.

Ter referentie: dit zijn de variabelen die het gehoste product zet. Met BILLING_ENABLED=true weigert de API te starten tenzij het lanceermoment en alle drie de Stripe-waarden gezet zijn.

VariabeleStandaardDoel
BILLING_ENABLEDfalseZet de Pro-pas, de paywall en het generatiequotum per niveau aan.
BILLING_PROVIDERstripeBetaalprovider. Alleen stripe is geïmplementeerd.
BILLING_LAUNCHED_ATleegISO-tijdstip van de lancering. Accounts die daarvoor zijn aangemaakt, krijgen bij hun volgende aanmelding 3 maanden Pro.
STRIPE_SECRET_KEYleegGeheime Stripe-sleutel (sk_live_… of een beperkte rk_live_…).
STRIPE_WEBHOOK_SECRETleegOndertekeningsgeheim (whsec_…) van het webhook-endpoint <api>/api/v1/billing/webhook.
STRIPE_PRICE_PRO_YEAR_PASSleegStripe Price-id van de eenmalige Pro-jaarpas.
GENERATION_QUOTA_PER_DAY_ANONYMOUS1Gegenereerde routes per dag voor bezoekers die niet aangemeld zijn (per IP) als betalingen aan staan. 0 schakelt de limiet uit.
GENERATION_QUOTA_PER_DAY_FREE3Hetzelfde voor aangemelde gebruikers op het gratis plan.
GENERATION_QUOTA_PER_DAY_PRO50Hetzelfde voor Pro-gebruikers.

Achter een reverse proxy zetten

De standaard-compose stelt poorten rechtstreeks beschikbaar. Voor TLS en een echt domein zet je een reverse proxy (Caddy, Traefik, ingress-nginx, Cloudflare Tunnel) voor de web- en api-services en override je de publieke URL's in .env:

PUBLIC_WEB_URL=https://routess.example.com
PUBLIC_API_URL=https://api.routess.example.com

PUBLIC_WEB_URL wordt ook gebruikt als OAuth-redirect-basis, dus die moet overeenkomen met wat je in Google Cloud hebt geconfigureerd.

Upgraden

Maak eerst een databaseback-up (zie hieronder); migraties zijn alleen voorwaarts, dus een snapshot is je terugrol-pad. Daarna:

docker compose -f docker/compose.selfhost.yaml --project-directory . pull
docker compose -f docker/compose.selfhost.yaml --project-directory . up -d

De API draait migraties automatisch bij het opstarten. Er is geen handmatige migratiestap. Om terug te rollen, herstel je de dump van voor de upgrade en pin je ROUTESS_TAG op de vorige release.

Back-up maken

De Postgres-data staat in het named volume postgres_data. Standaard pg_dump werkt:

docker compose -f docker/compose.selfhost.yaml --project-directory . exec postgres \
  pg_dump -U routess routess > routess-$(date +%F).sql

Herstel in een vers volume met psql:

docker compose -f docker/compose.selfhost.yaml --project-directory . exec -T postgres \
  psql -U routess routess < routess-2026-06-04.sql

Probleemoplossing

  • Is de API gezond? curl http://localhost:3000/health/ready geeft 200 wanneer de API de database kan bereiken; /health/live controleert enkel of het proces draait.
  • "address already in use" op :8080 of :3000: wijzig WEB_PORT / API_PORT in .env.
  • Google-aanmelding geeft redirect_uri_mismatch: de geautoriseerde redirect-URI van de OAuth-client moet exact overeenkomen met <PUBLIC_WEB_URL>/auth/callback.
  • Kaarttegels laden niet: controleer of VITE_MAPBOX_ACCESS_TOKEN is gezet; kijk in de browser-devtools naar 401's van api.mapbox.com.
  • Verificatie-e-mails komen niet aan: zet RESEND_API_KEY en EMAIL_FROM. Zonder die logt de API de verificatie-URL naar stdout; draai docker compose logs api | grep '\[email:console\]'.

On this page