maps.libre.is
HOWTO run your own map servers.
Debian
Using Debian stable (12/bookworm).
Install dependenices:
sudo apt install apache2 python3-certbot-apache \
osm2pgsql postgresql-postgis postgresql-postgis-scripts \
pkg-config libicu-dev virtualenv python3-pip \
build-essential python3-dev
Firewall
Open ports 80 and 443 for web.
Apache
Install and set up Apache.
certbot -d maps.libre.is -d map.libre.is
# remove old apache configs:
rm /etc/apache2/sites-enabled/000-default*
Add new apache configs to /etc/apache2/sites-available/maps-libre-is.conf:
<VirtualHost maps.libre.is:80>
ServerName maps.libre.is
ServerAlias map.libre.is
ServerAdmin webmaster@libre.is
DocumentRoot /var/www/html/maps-libre-is
ErrorLog ${APACHE_LOG_DIR}/error-libre-maps-is.log
CustomLog ${APACHE_LOG_DIR}/access-libre-maps-is.log combined
RewriteEngine on
ReWriteCond %{HTTPS} off
RewriteCond %{SERVER_NAME} =map.libre.is
RewriteRule ^ https://maps.libre.is%{REQUEST_URI} [END,NE,R=permanent]
ReWriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{SERVER_NAME} =maps.libre.is
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<VirtualHost maps.libre.is:443>
ServerName maps.libre.is
ServerAlias map.libre.is
ServerAdmin webmaster@libre.is
DocumentRoot /var/www/html/maps-libre-is
ErrorLog ${APACHE_LOG_DIR}/error-ssl-libre-maps-is.log
CustomLog ${APACHE_LOG_DIR}/access-ssl-libre-maps-is.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =map.libre.is
RewriteRule ^ https://maps.libre.is%{REQUEST_URI} [END,NE,R=permanent]
ReWriteCond %{HTTPS} off [OR]
ReWriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
ReWriteRule ^(.*)$ https://%1$1 [L,R=301]
<Directory /var/www/html/maps-libre-is>
Options FollowSymlinks
AllowOverride All
Require all granted
</Directory>
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/maps.libre.is/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/maps.libre.is/privkey.pem
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
Enable new configuration:
sudo mkdir -p /var/www/html/maps-libre-is
echo maps.libre.is | sudo tee /var/www/html/maps-libre-is/index.html
sudo ln -s /etc/apache2/sites-available/maps-libre-is.conf /etc/apache2/sites-enabled/maps-libre-is.conf
sudo systemctl restart apache2
Nominatim
“Nominatim uses OpenStreetMap data to find locations on Earth by name and address (geocoding). It can also do the reverse, find an address for any location on the planet.”
The full installation is quite demanding:
2GB RAM minimum.
Full planet import requires 128GB of RAM or more.
Full planet needs at least 1TB of fast disk.
Full import of planet takes 2.5 days on NVMe, 4-5 days on SSD.
With the large disk, create a mount in /srv.
Set up Nominatim user and switch to it.
sudo useradd -d /srv/nominatim -s /bin/bash -m nominatim
sudo -u nominatim bash
export USERNAME=nominatim
export USERHOME=/srv/nominatim
chmod a+x $USERHOME
Postgres
Postgres is needed by Nominatim.
export USERNAME=nominatim
export USERHOME=/srv/nominatim
sudo systemctl restart postgresql
sudo -u postgres createuser -s $USERNAME
sudo -u postgres createuser www-data
Edit /etc/postgresql/15/main/postgresql.conf thusly:
shared_buffers = 2GB
maintenance_work_mem = 10GB
autovacuum_work_mem = 2GB
work_mem = 50MB
synchronous_commit = off
max_wal_size = 1GB
checkpoint_timeout = 60min
checkpoint_completion_target = 0.9
random_page_cost = 1.0
wal_level = minimal
max_wal_senders = 0
Nominatim Install
As user nominatim.
sudo -u nominatim bash
export USERNAME=nominatim
export USERHOME=/srv/nominatim
virtualenv $USERHOME/nominatim-venv
$USERHOME/nominatim-venv/bin/pip install nominatim-db
. $USERHOME/nominatim-venv/bin/activate
Now import data, such as described here:
As the nominatim user:
mkdir -p ~/nominatim-project
mkdir -p /srv/nominatim/flatnode
cd ~/nominatim-project
export PROJECT_DIR=~/nominatim-project
# Replace flatnode.file with appropriate file name
Add this to ~/nominatim-project/.env
NOMINATIM_FLATNODE_FILE="/srv/nominatim/flatnode/flatnode.file"
Download some files:
export PROJECT_DIR=~/nominatim-project
cd $PROJECT_DIR
wget https://nominatim.org/data/wikimedia-importance.csv.gz
wget -O secondary_importance.sql.gz https://nominatim.org/data/wikimedia-secondary-importance.sql.gz
wget https://nominatim.org/data/us_postcodes.csv.gz
# Just North America for now (15GB):
# wget https://download.geofabrik.de/north-america-latest.osm.pbf
# Or perhaps just US:
wget https://www.osmtoday.com/north_america/us.pbf
# Uh, use venv
source /srv/nominatim/nominatim-venv/bin/activate
# Now import it (takes 15 hours)
nominatim import --osm-file us.pbf 2>&1 | tee setup.log
Set up for web:
$USERHOME/nominatim-venv/bin/pip install psycopg[binary] falcon uvicorn gunicorn
$USERHOME/nominatim-venv/bin/pip install nominatim-api
Create systemd files:
sudo tee /etc/systemd/system/nominatim.socket << EOFSOCKETSYSTEMD
[Unit]
Description=Gunicorn socket for Nominatim
[Socket]
ListenStream=/run/nominatim.sock
SocketUser=www-data
[Install]
WantedBy=multi-user.target
EOFSOCKETSYSTEMD
Another systemd file:
sudo tee /etc/systemd/system/nominatim.service << EOFNOMINATIMSYSTEMD
[Unit]
Description=Nominatim running as a gunicorn application
After=network.target
Requires=nominatim.socket
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=$USERHOME/nominatim-project
ExecStart=$USERHOME/nominatim-venv/bin/gunicorn -b unix:/run/nominatim.sock -w 4 -k uvicorn.workers.UvicornWorker nominatim_api.server.falcon.server:run_wsgi
ExecReload=/bin/kill -s HUP \$MAINPID
StandardOutput=append:/var/log/gunicorn-nominatim.log
StandardError=inherit
PrivateTmp=true
TimeoutStopSec=5
KillMode=mixed
[Install]
WantedBy=multi-user.target
EOFNOMINATIMSYSTEMD
Start Nominatim systemd:
sudo systemctl daemon-reload
sudo systemctl enable nominatim.socket
sudo systemctl start nominatim.socket
sudo systemctl enable nominatim.service
Nominatim Apache
Thusly.
As user nominatim:
mkdir $USERHOME/nominatim-project
As sudo user:
sudo a2enmod proxy_http
sudo tee /etc/apache2/conf-available/nominatim.conf << EOFAPACHECONF
#ProxyPass /nominatim "unix:/run/nominatim.sock|http://localhost/"
ProxyPass / "unix:/run/nominatim.sock|http://localhost/"
EOFAPACHECONF
sudo a2enconf nominatim
sudo systemctl restart apache2
Then connect to this to test:
Nominatim UI
Nominatim is just the API. It needs a nice front-end too.
Grab the latest release from here:
wget https://github.com/osm-search/nominatim-ui/releases/download/v3.5.3/nominatim-ui-3.5.3.tar.gz
tar xf nominatim-ui-3.5.3.tar.gz
cp -a nominatim-ui-3.5.3/dist/* /var/www/html/maps-libre-is/
Need to modify Apache again. Remove this file: /etc/apache2/conf-available/nominatim.conf
Final apache config:
<VirtualHost maps.libre.is:80>
ServerName maps.libre.is
ServerAlias map.libre.is
ServerAdmin webmaster@libre.is
DocumentRoot /var/www/html/maps-libre-is
ErrorLog ${APACHE_LOG_DIR}/error-libre-maps-is.log
CustomLog ${APACHE_LOG_DIR}/access-libre-maps-is.log combined
RewriteEngine on
ReWriteCond %{HTTPS} off
RewriteCond %{SERVER_NAME} =map.libre.is
RewriteRule ^ https://maps.libre.is%{REQUEST_URI} [END,NE,R=permanent]
ReWriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{SERVER_NAME} =maps.libre.is
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<VirtualHost maps.libre.is:443>
ServerName maps.libre.is
ServerAlias map.libre.is
ServerAdmin webmaster@libre.is
DocumentRoot /var/www/html/maps-libre-is
ErrorLog ${APACHE_LOG_DIR}/error-ssl-libre-maps-is.log
CustomLog ${APACHE_LOG_DIR}/access-ssl-libre-maps-is.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =map.libre.is
RewriteRule ^ https://maps.libre.is%{REQUEST_URI} [END,NE,R=permanent]
ReWriteCond %{HTTPS} off [OR]
ReWriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
ReWriteRule ^(.*)$ https://%1$1 [L,R=301]
<Directory /var/www/html/maps-libre-is>
DirectoryIndex search.html
Options FollowSymlinks
AllowOverride All
Require all granted
</Directory>
ProxyPass /nominatim "unix:/run/nominatim.sock|http://maps.libre.is/"
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/maps.libre.is/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/maps.libre.is/privkey.pem
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
Custom Title and URL
Set custom title and URL like this. Edit /var/www/html/maps-libre-is/theme/config.theme.js Change thusly:
Nominatim_Config.Nominatim_API_Endpoint = 'https://maps.libre.is/nominatim/';
Nominatim_Config.Page_Title = 'Libre Maps';
TODO
Note, this still serves tiles from tile.openstreetmap.org.
Note, this is still serving something from Fastly, probably CDN caching.