Makina Maps: On-Demand Vector and Raster Tiles from OpenStreetMap, Dockerized
Full Stack to Build, Serve and Update your own Vector and Raster Tiles from OpenStreetMap Data.
At a glance
- What is it?
- Makina Maps is a full-stack Docker Compose setup that builds, serves, and updates OpenStreetMap-derived vector and raster tiles on request, using OpenMapTiles and TileServer-GL. It trades pre-generated MBTiles archives for a live database and an NGINX cache, which makes updates fast but adds operational complexity.
- Who is it for?
- Adopt Makina Maps if you need a self-hosted tile server for a specific region, want to avoid pre-generating a full MBTiles archive, and require frequent updates from OSM. Skip it if you lack Docker experience, need a simple static tile server, or want a project with recent maintenance.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Probably not. The repository last received commits 43 months ago, on March 14, 2023.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 6, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The Problem: Tile Servers That Are Slow to Set Up and Slow to Update
Most self-hosted tile servers require you to pre-render an entire MBTiles archive. That process can take hours or days for a country-sized area, and every OSM update means re-rendering a large portion of the archive. Makina Maps takes a different route. It renders tiles on request from a live OpenMapTiles database. The README states this explicitly: "Makina Maps render tiles on request, no need to pre-generate all tiles on huge MBTiles archive: fast setup, fast update." The target user is a developer or small organization that wants to serve OSM-based tiles for a specific region, with the ability to refresh data incrementally. It is not aimed at someone who needs a static, read-only tile set with zero moving parts.
Architecture: Nginx, TileServer-GL, and Postserve in a Chain
The repository contains a Docker Compose setup that wires together four components. At the front is NGINX, which caches tiles and also expires them when the underlying data changes. Behind that sits TileServer-GL, which serves Mapbox GL styles, sprites, fonts, and can render raster PNG tiles from the vector source. The vector tiles themselves come from postserve, a service that generates them on the fly from the OpenMapTiles PostgreSQL database. The README includes an ASCII diagram showing the flow: a tilejson request goes from the client to NGINX, then to TileServer-GL, then to postserve. A PBF tile request follows the same path, but NGINX also fetches from postserve directly to fill its cache. Raster PNG tiles are rendered by TileServer-GL and cached by NGINX. This design means no component stores a full tile set. The database is the source of truth, and the cache is a temporary acceleration layer.
Getting Started: Clone, Build, Import, and Serve
The setup process is scripted but not one-command. You start by cloning with submodules: `git clone --recurse-submodules https://github.com/makina-maps/makina-maps.git`. Then you clone style repositories and fonts into the `tileserver-gl` directory, using branches like `gh-pages` from OpenMapTiles and Makina Corpus. After that, you build the Docker images with `docker-compose build` and pull the OpenMapTiles images with `cd openmaptiles && docker-compose pull`. Importing data is a three-step process. First, run `../scripts/10-import-generic.sh` to load non-OSM data. Second, run `../scripts/20-import-prepare.sh andorra` to download the Geofabrik extract and configure the area. Third, run `../scripts/30-import-extract.sh` to import that extract into the database. To start the server, you launch the database and postserve from the `openmaptiles` directory, then bring up the rest from the root: `docker-compose up`. The README gives a concrete example URL: `http://127.0.0.1:8080/data/v3.json` for the TileJSON, and `http://127.0.0.1:8080/styles/bright/{z}/{x}/{y}.png` for raster tiles. The configuration lives in `tileserver-gl/config.json`, which is a TileServer-GL config file with a Makina Maps extension called `remote_tilejson`.
Updating from OpenStreetMap: The Incremental Loop
The update path is where Makina Maps differs from a static tile server. After the initial import, you run `../scripts/40-update.sh` from the `openmaptiles` directory. The README says it "loops over pending updates, then wait for new update." You can stop it with CTRL-C, and it will finish the current update before quitting. The update mechanism relies on Imposm, which marks tiles as expired when OSM data changes. Then a script inside the NGINX container watches for those expirations and removes the corresponding cached tiles. This is a clean design: the database is updated, the cache is invalidated, and the next request for a tile triggers a fresh render. However, the README notes that the updater runs as a foreground process. If you stop it, you stop receiving updates. For a production deployment, you would need to run that script under a process manager or a cron job, which is not documented here.
Configuration Keys That Matter: remote_tilejson, domains, and Cache Size
The configuration file exposes several important settings. The `remote_tilejson` key is specific to Makina Maps and is not available in standard TileServer-GL. It tells TileServer-GL where to fetch vector tiles from, using an internal Docker hostname like `http://postserve:8090/`. The README shows that you can also point to a local MBTiles file instead, which gives you a fallback if you do not want the live database. The `domains` array is used only for raster tiles and should list publicly reachable hostnames. The vector TileJSON must be overwritten with public URLs, because the internal URLs are not reachable from outside the Docker network. The cache is controlled by two environment variables: `CACHE_KEYS_ZONE_SIZE` for in-memory key storage (default `50m`) and `CACHE_MAX_SIZE` for file storage (default `20g`). There is also a rate limit in the NGINX config, which you can bypass with a URL parameter `key` or by adding a host to a whitelist in `nginx/map`. These settings are concrete and testable, but the README gives no guidance on how to size them for a given traffic level.
Limitations and Failure Modes: The Wrong Tool for Static or Huge Deployments
The most obvious limitation is the project's inactivity. The last push was August 2020, and the latest release is v0.3. That means the pinned versions of OpenMapTiles, TileServer-GL, and the underlying Docker images are from that era. You may encounter compatibility issues with newer versions of Docker or with OSM data that has changed schema since then. The README itself warns that the `remote_tilejson` option is "specific to Makina Maps and not available in standard Tileserver-GL," so upgrading TileServer-GL could break that integration. Another limitation is that the initial import is not trivial. The benchmark table shows that a 220 MB extract like Aquitaine takes about 6 minutes on 8 CPUs, but that is after you have downloaded the data and tuned the area configuration. For a planet-scale deployment, the on-demand rendering model would be impractical because every tile request hits a database query. A pre-rendered MBTiles archive would be far more efficient for a global tile service. Finally, the update loop requires a running process and a working NGINX cache. If the cache expires incorrectly or the updater crashes, you could serve stale tiles without noticing.
Alternatives: OpenMapTiles Directly, or a Static MBTiles Server
The closest alternative is to use OpenMapTiles on its own, without the Makina Maps wrapper. OpenMapTiles provides the same database schema and a toolchain for generating MBTiles files. The difference is that Makina Maps adds the on-demand rendering layer and the update loop. With plain OpenMapTiles, you generate a static archive and serve it with a simple tile server like Tileserver-GL or MapServer. That approach is simpler to operate, but every data update requires re-generating the archive. Another alternative is to use a hosted tile service like MapTiler or Mapbox, which removes all infrastructure concerns but costs money and locks you into their platform. The trade-off is clear: Makina Maps offers a middle ground where you control the hardware and the data, but you accept the operational burden of a live database and a custom Docker setup. If you are comfortable with Docker and need frequent updates, the on-demand model is attractive. If you prefer a static file that you can host anywhere, the MBTiles route is more robust.
Maintenance and Upgrade Cost: What the Repository Layout Tells You
The repository is structured as a set of shell scripts and Docker Compose files. The scripts are numbered (`10-import-generic.sh`, `20-import-prepare.sh`, `30-import-extract.sh`, `40-update.sh`), which suggests a linear workflow. There is no CI configuration visible in the README, and no mention of automated tests. The license is BSD-3-Clause, which is permissive: you can modify and redistribute the code, but you must retain the copyright notice. The maintenance cost is tied to the underlying components. OpenMapTiles and TileServer-GL are actively maintained, but Makina Maps itself is not. To keep the stack working, you would need to manually update the submodules and the Docker images, and then verify that the `remote_tilejson` integration still works. The README mentions a development mode where you can disable the NGINX cache with `NGINX_DISABLE_CACHE=1`, which is useful for debugging but not for production. There is also a monitoring endpoint at `http://127.0.0.1:8082/nginx_status`, which gives you basic NGINX metrics. No other monitoring or logging is described.
Editorial conclusion
Adopt Makina Maps if you need a self-hosted tile server for a specific region, want to avoid pre-generating a full MBTiles archive, and require frequent updates from OSM. Skip it if you lack Docker experience, need a simple static tile server, or want a project with recent maintenance. Before adopting, verify the current compatibility of the pinned OpenMapTiles and TileServer-GL versions with your Docker environment, and test the update loop on a small extract like Andorra. The last push was August 2020, so plan for potential breakage with newer Docker or OSM data formats.
Frequently asked questions
What does Makina Maps actually do?
Makina Maps is a full stack to build, serve, and update your own vector and raster tiles from OpenStreetMap data. It renders tiles on request from the OpenMapTiles database and schema instead of pre-generating them into a large MBTiles archive.
What do I need installed before setting up Makina Maps?
The system dependencies are git, make, docker, and docker-compose. The project is then cloned with the recurse-submodules flag, and styles and fonts are cloned separately into the tileserver-gl directory.
How do I import an OpenStreetMap extract into Makina Maps?
From the openmaptiles directory, run ../scripts/10-import-generic.sh for generic data, then ../scripts/20-import-prepare.sh with a Geofabrik area name, then ../scripts/30-import-extract.sh. The prepare and extract scripts can be replayed with the same or another area.
How does Makina Maps keep tiles up to date, and how is the cache expired?
Run ../scripts/40-update.sh, which loops over pending updates and then waits for a new one; CTRL-C quits at the end of the current update. Imposm marks tiles to expire, and a script in the NGINX container watches and expires them in the cache.
Which URLs does Makina Maps serve after startup?
Assuming a local host, the demo is at http://127.0.0.1:8080, the OpenMapTiles TileJSON at http://127.0.0.1:8080/data/v3.json, the Bright GL style at http://127.0.0.1:8080/styles/bright/style.json, the Bright raster TileJSON at http://127.0.0.1:8080/styles/bright.json, and raster tiles at http://127.0.0.1:8080/styles/bright/{z}/{x}/{y}.png.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/makina-maps-makina-maps)