> ## Content Index
> Fetch the complete content index at: https://blog.afi.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# Run a free geocoder with Nominatim Docker
- URL: https://blog.afi.io/blog/run-a-free-geocoder-with-nominatim-docker/
- Published: 2024-03-17T22:57:20.000Z
- Updated: 2025-08-15T18:16:16.000Z
- Description: A step by step guide to setting up a free geocoding and reverse geocoding service using Docker.
- Author: Afian Anwar
- Tags: osm

The fastest way to set up a free geocoding and reverse geocoding service on your local machine is by installing [Nominatim](https://nominatim.org/?ref=blog.afi.io) using [Docker](https://www.docker.com/?ref=blog.afi.io). In this tutorial, I'll walk you through the process and explain what happens at each step along the way. Once Nominatim is up and running, we'll run a quick geocoding example to check that it works.

Part 1: [OpenStreetMap OSM Nominatim API tutorial ](https://afi.io/blog/openstreetmap-osm-nominatim-api-tutorial/?ref=blog.afi.io)  
**Part 2: Run a free geocoder with Nominatim Docker (this article)**  
Part 3: [Building a free geocoding and reverse geocoding service with OpenStreetMap](https://www.afi.io/blog/building-a-free-geocoding-and-reverse-geocoding-service-with-openstreetmap/?ref=blog.afi.io)  
Part 4: [How to draw and view boundary data with OpenStreetMap OSM](https://www.afi.io/blog/how-to-draw-and-view-boundary-data-with-openstreetmap-osm/?ref=blog.afi.io)

### How Nominatim works

Nominatim is a geocoding and reverse geocoding software package that is commonly used to convert addresses into geographic coordinates (latitude and longitude) and vice versa.

You can think of Nominatim as a specialized search engine for OpenStreetMap (OSM) data. OSM organizes data as a graph, with `places` (e.g. a specific building address) as nodes connected by roads to other places. Each `place` is annotated with tags describing its name, address, coordinates, function etc. 

![Nominatim works by extracting place data from OpenStreetMap turning it into a free geocoder](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2024/03/diagram--2-.png)

Nominatim works by extracting place data from OpenStreetMap

Nominatim unwraps this graph and stores it in database tables where it can be efficiently queried. For example, each `place` then becomes a row entry in the `places` table, with columns for name, address, coordinates etc. Relationships between places are encoded as references to different rows.

So let's say you want to geocode (convert an address name to a latitude, longitude pair) the address, "999 Canada Place". The address string can be found in the name column of the `places` table which is specifically designed to handle free text search efficiently. This means that when an address is inserted into the database, a separate lookup table that maps words or phrases to the row entries they occur in is also updated, which allows for fast searching based on address names or phrases. Nominatim uses [Postgres](https://www.postgresql.org/?ref=blog.afi.io), but the principles I've described here apply to any relational database.

### **Install Docker and spin up Nominatim**

To run Nominatim, we are going to use [Docker](https://www.docker.com/?ref=blog.afi.io), a program that packages software into standardized units called containers that have everything the software needs to run including libraries, system tools, code, and runtime.

Download [Docker Desktop](https://docs.docker.com/desktop/install/mac-install/?ref=blog.afi.io) and start it so that it runs in the background. Next, in the preferences section, make sure that you configure docker to run with enough memory and disk space because we'll be extracting map data from OSM and using it to populate several database tables, and this consumes disk storage. Set **disk image size** to at least 8 GB and **memory** to 20 GB.

![Docker memory and disk space configuration for Nominatim Docker set up and install](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2024/03/Screen-Shot-2024-03-17-at-2.28.51-PM.png)

Docker memory and disk space configuration for Nominatim Docker set up and install

Finally, run the command:

```bash
docker run -it \
  -e PBF_URL=http://download.geofabrik.de/north-america/canada/british-columbia-latest.osm.pbf \
  -e REPLICATION_URL=https://download.geofabrik.de/north-america/canada/british-columbia-updates/ \
  -p 8080:8080 \
  --name nominatim \
  mediagis/nominatim:4.3
```

This sets up a Nominatim container instance (pulled from the [mediagis/nominatim v4.3 repository](https://github.com/mediagis/nominatim-docker/tree/master/4.3?ref=blog.afi.io)) using OSM data for British Columbia, Canada, allowing you to access a geocoding service via HTTP on port 8080 of your host machine. Additionally, it configures the container to receive incremental updates (via the `REPLICATION_URL`) to stay synchronized with changes in OSM data.

![Nominatim docker progress bar](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2024/03/Screen-Shot-2024-03-16-at-8.49.24-PM.png)

Nominatim docker progress bar

Once you hit enter, you'll see a progress bar that shows you how much time the download has left.

### Extracting map data to Postgres

Once the download is complete, the install script unpacks the OSM map data and saves it into Postgres using the [osm2pgsql](https://osm2pgsql.org/?ref=blog.afi.io) utility.

![osm2pgsql extracts the OSM map data and saves it into Postgres](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2024/03/Screen-Shot-2024-03-16-at-9.58.43-PM.png)

osm2pgsql extracts the OSM map data and saves it into Postgres

When this is done, you'll get a message saying, "Nominatim is ready to accept requests".

![Nominatim Docker is installed and ready to accept API requests](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2024/03/Screen-Shot-2024-03-16-at-10.10.10-PM.png)

Nominatim Docker is installed and ready to accept API requests

### Testing our free geocoder

The final step involves verifying the functionality of the Nominatim API through a basic geocoding example. Assuming you've followed all the previous instructions, our free geocoding service should now be operational at [http://localhost:8080](http://localhost:8080/?ref=blog.afi.io). To test it, please open a new browser tab and navigate to the following address: [http://localhost:8080/search?q=canada+place](http://localhost:8080/search?q=canada+place&ref=blog.afi.io).

![The Nominatim API free geocoding service returning a query result](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2024/03/Screen-Shot-2024-03-16-at-10.48.38-PM.png)

The Nominatim API returning a query result

You should get back the following response:

```
[
    {
        "place_id": 579864,
        "licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
        "osm_type": "way",
        "osm_id": 706831744,
        "boundingbox": [
            "49.2877544",
            "49.2881403",
            "-123.115517",
            "-123.114108"
        ],
        "lat": "49.287991",
        "lon": "-123.1149786",
        "display_name": "Canada Place, Gastown, Downtown, Vancouver, Metro Vancouver Regional District, V6C, Canada",
        "place_rank": 26,
        "category": "highway",
        "type": "tertiary",
        "importance": 0.30000999999999994
    },
    // ... removed similar entries
    {
        "place_id": 579858,
        "licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
        "osm_type": "node",
        "osm_id": 7515805468,
        "boundingbox": [
            "49.2879188",
            "49.2880188",
            "-123.1147061",
            "-123.1146061"
        ],
        "lat": "49.2879688",
        "lon": "-123.1146561",
        "display_name": "Canada Place, West Waterfront Road, Gastown, Downtown, Vancouver, Metro Vancouver Regional District, V6C, Canada",
        "place_rank": 30,
        "category": "highway",
        "type": "bus_stop",
        "importance": 0.20000999999999997
    }
]
```

which is an array of all the `places` that correspond to the search term "Canada Place" ([Vancouver's downtown cruise terminal](https://www.aubergevancouver.com/blog/things-to-do-at-canada-place/?ref=blog.afi.io)). The `lat` and `lon` fields represent the geocoded coordinates of each `place`.

Now that we've gotten our free geocoder working locally, the next step is to use the Nominatim API to build a free geocoding and reverse geocoding service.

👋 **As always, if you have any questions or suggestions for me, please** [**reach out**](https://yourls.afi.io/newcontact?ref=blog.afi.io) **or** [**say hello on LinkedIn**](https://www.linkedin.com/in/afian-anwar-a023b143/?ref=the-afi-labs-blog)**.**

Next: [Part 3: Building a free geocoding and reverse geocoding service with OpenStreetMap](https://www.afi.io/blog/building-a-free-geocoding-and-reverse-geocoding-service-with-openstreetmap/?ref=blog.afi.io)