A Corviont stack runs maps, routing, and search fully offline on your device. Once started, your application talks to a single local HTTP entrypoint — no external map APIs required.
The stack includes:
linux/amd64 and linux/arm64.To check your architecture on Linux / Raspberry Pi:
uname -m
# x86_64 or aarch64 => OK
getconf LONG_BIT
# 64 => OK
Quick sanity check:
# Both should output a version
docker version
docker compose version
The fastest way to get a Corviont stack running today is the Monaco demo published as a Docker Compose stack on GitHub: github.com/corviont/monaco-demo.
git clone https://github.com/corviont/monaco-demo.git
cd monaco-demo
Set the port you want the stack to listen on (3000 is the default used
in this documentation). This creates a .env file that
Docker Compose will pick up automatically:
echo "CORVIONT_PORT=3000" > .env
If you want to call Corviont APIs from a browser app running on a different origin (e.g. http://localhost:3001), append this to your .env:
# Supports a comma-separated allowlist (e.g. http://localhost:3001,http://localhost:5173) or "*" to allow any origin
echo "CORVIONT_CORS_ALLOWED_ORIGINS=http://localhost:3001" >> .env
Start all services in the background. On some Linux / Raspberry Pi setups
you may need to prefix commands with sudo.
docker compose up -d
Once the stack starts, open http://localhost:3000/ in your browser. You should see:
cafe)To stop all services and free ports:
docker compose down
CORVIONT_PORT or Docker permissions.
http://localhost:3000. All examples below assume that base URL.
Use this if you want the “it just works” path. Corviont provides a ready-to-use MapLibre style based on OpenMapTiles that already references the correct tiles and assets for the dataset version.
<html>
<head>
<!--
NOTE: For simplicity, this example uses unpkg for MapLibre.
Corviont deployments bundle MapLibre (and all other assets) locally for fully offline use.
-->
<script src='https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.js'></script>
<link href='https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.css' rel='stylesheet' />
<style>
html, body, #map { height: 100%; width: 100%; padding: 0; margin: 0; }
</style>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
async function initMap() {
// dataset.json provides the active dataset version (used for versioned asset URLs)
const dataset = await (await fetch("/dataset.json")).json();
new maplibregl.Map({
container: "map",
center: [7.42, 43.732], // Monaco
zoom: 15,
// Corviont styles use relative URLs; MapLibre requires absolute URLs.
// rewrite any relative request to an absolute one.
transformRequest: (url) => ({ url: /^https?:\/\//i.test(url) ? url : `${window.location.origin}/${url}` }),
}).setStyle(`map-style/${dataset.version}.json`, {
// make sprite/glyph URLs absolute (style contains relative paths)
transformStyle: (_, next) => ({
...next,
sprite: `${window.location.origin}/${next.sprite}`,
glyphs: `${window.location.origin}/${next.glyphs}`,
})
});
}
initMap().catch(console.error);
</script>
</body>
</html>
Use this if you want a custom style (based on Corviont’s default, another OpenMapTiles style, or something you build from scratch) wired directly to the raw vector tiles.
<html>
<head>
<!--
NOTE: For simplicity, this example uses unpkg for MapLibre.
Corviont deployments bundle MapLibre (and all other assets) locally for fully offline use.
-->
<script src='https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.js'></script>
<link href='https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.css' rel='stylesheet' />
<style>
html, body, #map { height: 100%; width: 100%; padding: 0; margin: 0; }
</style>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
async function initMap() {
const dataset = await (await fetch("/dataset.json")).json();
new maplibregl.Map({
container: "map",
center: [7.42, 43.732],
zoom: 15,
style: {
version: 8,
sources: {
corviont: {
type: "vector",
tiles: [`${window.location.origin}/tiles/${dataset.version}/{z}/{x}/{y}.mvt`]
}
},
layers: [
// minimal example, displays roads only
{ id: "roads", type: "line", source: "corviont", "source-layer": "transportation" }
]
}
});
}
initMap().catch(console.error);
</script>
</body>
</html>
Use this to draw routes in your UI or power navigation features.
const input = {
locations: [{ "lat": 43.7336, "lon": 7.4200 }, { "lat": 43.7370, "lon": 7.4270 }],
costing: "auto",
directions_options: { units: "kilometers" },
// Easiest to render in MapLibre: OSRM response + GeoJSON route geometry
format: 'osrm',
shape_format: "geojson"
};
const url = "/router/route?json=" + encodeURIComponent(JSON.stringify(input));
const output = await (await fetch(url)).json();
/router proxies the Valhalla API (see the
full Valhalla API overview).
In the current Corviont stack, only
/router/route
is officially supported. Other Valhalla endpoints may be reachable but should be considered experimental.
Use this for a search box (forward geocoding).
// default limit is 5, max is 10
const output = await (await fetch('/geocoder/search?query=cafe&limit=7')).json();
// outputs [{"id":806,"type":"poi","name":"Loga Café","country":"MC","city":"","street":"Boulevard des Moulins","housenumber":"","postcode":"98000","lat":43.7434398,"lon":7.4283176}, ...]
console.log(output);
Use this for “tap to get address” or “what’s here?” interactions.
// default limit is 5, max is 10
const output = await (await fetch('/geocoder/reverse?lat=43.7434398&lon=7.4283176&limit=10&radius_m=100')).json();
// outputs [{"id":806,"type":"poi","name":"Loga Café","country":"MC","city":"","street":"Boulevard des Moulins","housenumber":"","postcode":"98000","lat":43.7434398,"lon":7.4283176}, ...]
console.log(output);
CORVIONT_PORT is missing
When running the stack, make sure you have a .env file
in the root of the cloned repository and that it contains:
CORVIONT_PORT=3000
Then restart the stack:
docker compose down
docker compose up -d
no matching manifest for linux/arm/v7
Images are built only for 64-bit architectures
(linux/amd64 and linux/arm64). If your
system is 32-bit (for example armv7l), Docker cannot
pull these images.
Check your architecture:
uname -m
# x86_64 or aarch64 => OK
getconf LONG_BIT
# 64 => OK
permission denied for /var/run/docker.sockOn some Linux / Raspberry Pi setups, Docker requires root access. You can either:
docker group (recommended):
sudo groupadd docker 2>/dev/null || true
sudo usermod -aG docker "$USER"
# Log out and log back in so the new group is applied
groups # should now include "docker"
Then retry:
docker compose up -d
sudo:
sudo docker compose up -d
After the initial image and data download, Corviont runs fully offline: tiles, routing, and geocoding are all served from containers on your host or device. Your UI talks only to the local HTTP entrypoint.
The Monaco demo shows one way to run a Corviont stack locally: github.com/corviont/monaco-demo.
The form has been successfully submitted.