Install Everything You Need
Debian 10 x64 (buster) 1 vCPU 1GB / 25GB Disk (NVMe SSD)
Update System
Make sure all packages are are up-to-date by running:
sudo apt update -qq
update:
sudo apt update && sudo apt upgrade --yes
Since there could be kernel updates consider system reboot after the upgrade.
Install PostgreSQL 13.3
backup of sorces list:
sudo cp /etc/apt/sources.list{,.aux}`
Create the file repository configuration:
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
Import the repository signing key:
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
Update the package lists:
sudo apt update
Install the latest version of PostgreSQL, If you want a specific version, use postgresql-12 or similar instead of postgresql:
sudo apt-get -y install postgresql
Verificate instalation:
sudo -u postgres psql --version
For more info: Download Postgresql
Install PHP 8
PHP 8 packages for Debian are available on the DEB.SURY.ORG repository.
Install required dependencies:
sudo apt install ca-certificates apt-transport-https software-properties-common --yes
Add the PHP packages APT repository:
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list
Import the repository signing key:
wget -qO - https://packages.sury.org/php/apt.gpg | sudo apt-key add -
Update the package lists:
sudo apt update
sudo apt upgrade
Note:
if you install php8.0 you install many unnecessary packages, since the only thing we need is cgi support. You can test which packages you are going to install:
sudo apt install php -s
Installing the Required Software
Now you can install all packages needed for Nominatim:
sudo apt install php-cgi
sudo apt install curl build-essential cmake g++ libboost-dev libboost-system-dev \
libboost-filesystem-dev libexpat1-dev zlib1g-dev \
libbz2-dev libpq-dev libproj-dev postgresql-13-postgis-3 postgresql-server-dev-13 \
php php-pgsql php-intl libicu-dev python3-dotenv \
python3-psycopg2 python3-psutil python3-jinja2 python3-icu
Creating Dedicated User Accounts
Nominatim will run as a global service on your machine. It is therefore best to install it under its own separate user account. In the following we assume this user is called nominatim and the installation will be in /srv/nominatim
. To create the user and directory run:
sudo useradd -d /srv/nominatim -s /bin/bash -m nominatim
Make sure that system servers can read from the home directory:
chmod a+x /srv/nominatim
Create Postgres users:
Create user for write and read(webservice):
sudo -u postgres createuser -s nominatim
sudo -u postgres createuser www-data
List roles user:
sudo -u postgres psql -c '\du'
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
nominatim | Superuser, Create role, Create DB | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
www-data | | {}
Note: To be sure who the user of the web service is:
getent passwd {0..6000}|grep -i 'www'
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
Setting up PostgreSQL
Tuning the PostgreSQL database
You might want to tune your PostgreSQL installation so that the later steps make best use of your hardware. You should tune the following parameters in your postgresql.conf file.
sudo -u postgres vim /etc/postgresql/13/main/postgresql.conf
shared_buffers = 2GB
maintenance_work_mem = (10GB)
autovacuum_work_mem = 2GB
work_mem = (50MB)
effective_cache_size = (24GB)
synchronous_commit = off
checkpoint_segments = 100 # only for postgresql 9.4
checkpoint_timeout = 10min
checkpoint_completion_target = 0.9
The numbers in brackets behind some parameters seem to work fine for 64GB RAM machine. Adjust to your setup. A higher number for max_wal_size means that PostgreSQL needs to run checkpoints less often but it does require the additional space on your disk.
Some parameter that they working for my with 1G of RAM:
shared_buffers = 128MB
maintenance_work_mem = 64MB
autovacuum_work_mem = -1
work_mem = 4MB
effective_cache_size = 200MB
synchronous_commit = off
max_wal_size = 1GB
min_wal_size = 80MB
checkpoint_timeout = 10min
checkpoint_completion_target = 0.5
Autovacuum must not be switched off because it ensures that the tables are frequently analysed. If your machine has very little memory, you might consider setting:
autovacuum_max_workers = 1
and even reduce autovacuum_work_mem further. This will reduce the amount of memory that autovacuum takes away from the import process.
For the initial import, you should also set:
fsync = off
full_page_writes = off
Don’t forget to reenable them after the initial import or you risk database corruption.
sudo systemctl restart postgresql.service
Install Nominatim
sudo su - nominatim
curl -O https://nominatim.org/release/Nominatim-3.7.2.tar.bz2
tar xf Nominatim-3.7.2.tar.bz2
The code must be built in a separate directory:
mkdir build
cd $_
cmake $HOME/Nominatim-3.7.2
make
sudo make install
Note: If for any reason you have to recompile, don’t forget to do it first make clean
Nominatim is now ready to use. verificate that command-line nominatim works:
nominatim -h
Importing the Database
Creating the project directory
sudo su - nominatim
export PROJECT_DIR=~/nominatim-planet
mkdir $PROJECT_DIR
cd $_
Configuration setup in .env
You can also set the same configuration via environment variables. All settings have a NOMINATIM_ prefix to avoid conflicts with other environment variables. $HOME/Nominatim-3.7.2/settings/env.defaults for a full list.
Downloading additional data
Wikipedia/Wikidata rankings
This data is available as a binary download. Put it into your project directory:
cd $PROJECT_DIR
curl -O https://www.nominatim.org/data/wikimedia-importance.sql.gz
The file is about 400MB and adds around 4GB to the Nominatim database.
Choosing the data to import
Using an extract
If you only need geocoding for a smaller region, then precomputed OSM extracts are a good way to reduce the database size and import time. Geofabrik offers extracts for most countries.
Dropping Data Required for Dynamic Updates
--no-updates
Reverse-only Imports
--reverse-only
(This saves about 5% of disk space)
Filtering Imported Data
settings/import-admin.style
Only import administrative boundaries and places.settings/import-street.style
Like the admin style but also adds streets.settings/import-address.style
Import all data necessary to compute addresses down to house number level.settings/import-full.style
Default style that also includes points of interest.settings/import-extratags.style
Like the full style but also adds most of the OSM tags into the extratags column.
The style can be changed with the configuration NOMINATIM_IMPORT_STYLE.
Initial import of the data
Important: First try the import with a small extract, for example from Geofabrik.
cd $PROJECT_DIR
curl -O https://download.geofabrik.de/south-america/colombia-latest.osm.pbf
PostgreSQL blocks at least the part of RAM that has been configured with the shared_buffers
parameter during PostgreSQL tuning and needs some memory on top of that.
In addition it needs to maintain a cache for node locations. The size of this cache can be configured with the parameter --osm2pgsql-cache
.
Then issue the following command from the build directory to start the import:
nominatim import --osm-file colombia-latest.osm.pbf 2>&1 | tee setup
Once you see messages with Rank .. ETA appear, the indexing process has started. I recommend you send the process to the background and go for coffee.
Troubleshooting:
If it does not happen the first time because postgres closed the connection, restart the postgres and launch again.
Drop database:
sudo -u postgres dropdb nominatim
Send the process to the background:
firt stop the process Ctrl+z
then send the process to the background with bg
command
Size of cache:
For the characteristics of my PC, I have configured the import with the following cache.
nominatim import --osm-file colombia-latest.osm.pbf --osm2pgsql-cache 250 2>&1 | tee setup
Testing the installation
verify all required tables and indices got created successfully:
cd $PROJECT_DIR
nominatim admin --check-database
Now you can try out your installation by running:
nominatim serve
This runs a small test server normally used for development.
curl http://localhost:8088/status.php
you should see an "OK"
You can also run a search query, e.g. curl http://localhost:8088/search.php?q=Manizales
Tuning the database
To recompute word counts run:
cd $PROJECT_DIR
nominatim refresh --word-counts
You can also defer that step to a later point in time when you realise that performance becomes an issue. Just make sure that updates are stopped before running this function.
If you want to be able to search for places by their type through special key phrases you also need to import these key phrases like this:
nominatim special-phrases --import-from-wiki
this command downloads the phrases from the wiki link above.
Setting up a web server
The web server should serve the php scripts from the website directory of your project directory. Therefore set up a project directory and populate the website directory:
mkdir $HOME/nominatim-project
cd $_
nominatim refresh --website
Using nginx
IMPORTANT: Nominatim project directory is located in /srv/nominatim/nominatim-project
and that you have installed Nominatim using the default installation prefix /usr/local
. We further assume that your web server runs as user www-data
.
Nginx has no native support for php scripts and you need to set up php-fpm for this purpose. First install nginx and php-fpm:
sudo apt update && sudo apt upgrade
sudo apt install nginx php-fpm
Making the website directory accessible
You need to make sure that the website directory is accessible for the web server user. You can check that the permissions are correct by accessing on of the php files as the web server user:
sudo -u www-data head -n 1 /srv/nominatim/nominatim-project/website/search.php
If this shows a permission error, we must give it the execution permissions for www-data
.
Configure php-fpm and Nginx
sudo mv /etc/php/8.0/fpm/pool.d/www.conf{,.aux}
Note: If you want to leave only the lines that are without comment you can do: sed -i '/^;/d' /etc/php/8.0/fpm/pool.d/www.conf
By default php-fpm listens on a network socket. If you want it to listen to a Unix socket instead, change the pool configuration /etc/php//fpm/pool.d/www.conf
as follows (for Dynamic or ondemand):
Dynamic
sudo tee /etc/php/8.0/fpm/pool.d/www.conf << EOF_PHP_FPM_CONF_DYNAMIC
[www]
; Replace the tcp listener and add the unix socket
listen = /var/run/php/php8.0-fpm.sock
; Ensure that the daemon runs as the correct user
listen.owner = www-data
listen.group = www-data
listen.mode = 0666
; Unix user of FPM processes
user = www-data
group = www-data
; Choose process manager type (static, dynamic, ondemand)
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
EOF_PHP_FPM_CONF_DYNAMIC
Ondemand
sudo tee /etc/php/8.0/fpm/pool.d/www.conf << EOF_PHP_FPM_CONF_ONDEMAND
[www]
user = www-data
group = www-data
listen = /var/run/php/php8.0-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0666
pm = ondemand
pm.max_children = 5
pm.process_idle_timeout = 10s;
EOF_PHP_FPM_CONF_ONDEMAND
Tell nginx that php files are special and to fastcgi_pass to the php-fpm unix socket by adding the location definition to the default configuration, create a Nginx configuration to forward http requests to that socket.
sudo mv /etc/nginx/sites-available/default{,.aux}
sudo tee /etc/nginx/sites-available/default << EOF_NGINX_CONF
server {
listen 83 default_server;
listen [::]:83 default_server;
root /srv/nominatim/nominatim-project/website;
index search.php index.html;
location / {
try_files $uri $uri/ @php;
}
location @php {
fastcgi_param SCRIPT_FILENAME "$document_root$uri.php";
fastcgi_param PATH_TRANSLATED "$document_root$uri.php";
fastcgi_param QUERY_STRING $args;
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
fastcgi_index search.php;
include fastcgi.conf;
}
}
EOF_NGINX_CONF
Test and Restart Nginx
verificate if you have errors in your configuration:
sudo nginx -t
sudo systemctl restart php8.0-fpm.service nginx.service
The Nominatim API is now available at curl http://localhost:83/status.php
. you should see an "OK"
Testing reverse geocoding
echo -e "GET http://127.0.0.1/reverse.php?format=json&lat=5.06889&lon=-75.51738&zoom=18&addressdetails=1 HTTP/1.0\n\n"|nc 127.0.0.1 83 | less