Skip to main content

Build Your Own OpenStreetMap Tile Server on Ubuntu 16.04

openstreetmap server

OpenStreetMap, aka, OSM is a user contributed world map that is freely editable. This tutorial will show you how to build your own OpenStreetMap tile server on Ubuntu 16.04. 2GB RAM, 40GB disk space should be the minimum OpenStreetMap server requirements.

Step 1: Upgrade Software

sudo apt update

sudo apt upgrade

Step 2: Install PostgreSQL Database Server with PostGIS

We will use PostgreSQL to store map data. PostGIS is a geospatial extenstion to PostgreSQL. Run the following commands to install them.

sudo apt install postgresql postgresql-contrib postgis postgresql-9.5-postgis-2.2

A user named postgres will be created during the installation process. This allows the use of peer authentication. Let’s switch to the postgres user:

sudo -u postgres -i

Create a PostgreSQL database user osm.

createuser osm

Create a database named gis and at the same time make osm as the owner of the database. -E UTF8 specifies the character encoding scheme to be used in the database is UTF8.

createdb -E UTF8 -O osm gis

Create hstore and postgis extension.

psql -c "CREATE EXTENSION hstore;" -d gis

psql -c "CREATE EXTENSION postgis;" -d gis

Exit from the postgres user.


Create osm user on your operating system so the tile server can run as osm user.

sudo adduser osm

Step 3: Download Map Stylesheet and Map Data

First switch to osm user

su - osm

Download the latest CartoCSS map stylesheets to the osm user’s home directory.


Extract it.

tar xvf v2.41.0.tar.gz

Next, download map data to the osm user’s home directory. Use the below command to download the map data of the whole planet (32G).

wget -c

If you want a map of individual country or state, go to Also, provides extracts of more than 200 cities and regions world-wide in different formats.

For example, download the map data of Great Britain (847M).

wget -c

Now exit from the osm user.


Recommendations before Importing Map Data

Importing map data takes a lot of RAM. If your physical memory is small, you can easily add a swap file. First we use fallocate command to create a file. For example, create a file named swapfile with 2G capacity in root file system:

sudo fallocate -l 2G /swapfile

Then make sure only root can read and write to it.

sudo chmod 600 /swapfile

Format it to swap:

sudo mkswap /swapfile


Setting up swapspace version 1, size = 2097148 KiB
no label, UUID=h32b3e10-0779-4865-9ea0-6e2af8f3kea9

Enable the swap file

sudo swapon /swapfile

The import process can take some time. It’s recommended to configure SSH keepalive so that you don’t lose the SSH connection. It’s very easy to do. Just open the SSH client configuration file on your local Linux machine.

sudo nano /etc/ssh/ssh_config

And paste the following text at the end of the file.

ServerAliveInterval 60

Then save the file and connect to your Ubuntu 16.04 server

Step 4: Import the Map Data to PostgreSQL

To import map data, we need to install osm2pgsql which converts OpenStreetMap data to postGIS-enabled PostgreSQL databases.

sudo apt install osm2pgsql

Switch to osm user again.

su - osm

Run the following command to load map stylesheet and map data into the gis Database. Replace great-britain-latest.osm.pbf with your own map data file.

osm2pgsql --slim -d gis -C 3600 --hstore -S openstreetmap-carto-2.41.0/ great-britain-latest.osm.pbf

osm2gpsql will run in slim mode which is recommended over the normal mode. -d stands for --database. -C flag specify the cache size in MB. Bigger cache size results in faster import speed but you need to have enough RAM to use cache. -S flag specify the style file. And finally you need to specify the map data file.

Once the import is complete, exit from the osm user.


Step 5: Install mod_tile

mod_tile is an Apache module that is required to serve tiles. Currently no binary package is available for Ubuntu. We can compile it from Github repository.

First install build dependency.

sudo apt install git autoconf libtool libmapnik-dev apache2-dev

Then clone the repository from Github.

git clone

cd mod_tile/

Compile and install

sudo make install
sudo make install-mod_tile

Step 6: Generate Mapnik Stylesheet

Install required packages.

sudo apt install curl unzip gdal-bin mapnik-utils node-carto

Switch to osm user.

su - osm

Cd into the carto style directory.

cd openstreetmap-carto-2.41.0/

Get shapefiles.


Now build the Mapnik xml stylesheet.

carto project.mml > style.xml

Exit from the osm user.


Step 7: Configuring renderd

Edit renderd config file.

sudo nano /usr/local/etc/renderd.conf

In the [default] section, change the value of XML and HOST to the following.


In [mapnik] section, change the value of plugins_dir.


Save the file.

Install renderd init script by copying the sample init script.

sudo cp mod_tile/debian/renderd.init /etc/init.d/renderd

Grant execute permission.

sudo chmod a+x /etc/init.d/renderd

Edit the init script file

sudo nano /etc/init.d/renderd

Change the following variable.

DAEMON_ARGS="-c /usr/local/etc/renderd.conf"

Save the file.

Create the following file and set osm the owner.

sudo mkdir -p /var/lib/mod_tile

sudo chown osm:osm /var/lib/mod_tile

Then start renderd service

sudo systemctl daemon-reload

sudo systemctl start renderd

sudo systemctl enable renderd

Step 8: Configure Apache

Install Apache web server

sudo apt install apache2

Create a module load file.

sudo nano /etc/apache2/mods-available/mod_tile.load

Paste the following line into the file.

LoadModule tile_module /usr/lib/apache2/modules/

Create a symlink.

sudo ln -s /etc/apache2/mods-available/mod_tile.load /etc/apache2/mods-enabled/

Then edit the default virtual host file.

sudo nano /etc/apache2/sites-enabled/000-default.conf

Past the following line in <VirtualHost *:80>

LoadTileConfigFile /usr/local/etc/renderd.conf
ModTileRenderdSocketName /var/run/renderd/renderd.sock
# Timeout before giving up for a tile to be rendered
ModTileRequestTimeout 0
# Timeout before giving up for a tile to be rendered that is otherwise missing
ModTileMissingRequestTimeout 30

Save and close the file. Restart Apache.

sudo systemctl restart apache2

Then in your web browser address bar, type


You should see the tile of world map. Congrats! You just successfully built your own OSM tile server.

Display Your Tiled Web Map

Tiled web map is also known as slippy map in OpenStreetMap terminology. There are two free and open source JavaScript map libraries you can use for your tile server: OpenLayer and Leaflet. The advantage of Leaflet is that it is simple to use and your map will be mobile-friendly.


To display your slippy map with OpenLayer, first create a web folder.

sudo mkdir /var/www/osm

Then download JavaScript and CSS from and extract it to the web root folder.

Next, create the index.html file.

sudo nano /var/www/osm/index.html

Paste the following HTML code in the file. Replace red-colored text and adjust the longitude, latitude and zoom level according to your needs.

<!DOCTYPE html>
<title>Accessible Map</title>
<link rel="stylesheet" href="http://your-ip/ol.css" type="text/css">
<script src="http://your-ip/ol.js"></script>
  a.skiplink {
    position: absolute;
    clip: rect(1px, 1px, 1px, 1px);
    padding: 0;
    border: 0;
    height: 1px;
    width: 1px;
    overflow: hidden;
  a.skiplink:focus {
    clip: auto;
    height: auto;
    width: auto;
    background-color: #fff;
    padding: 0.3em;
  #map:focus {
    outline: #4A74A8 solid 0.15em;
  <a class="skiplink" href="#map">Go to map</a>
  <div id="map" class="map" tabindex="0"></div>
  <button id="zoom-out">Zoom out</button>
  <button id="zoom-in">Zoom in</button>
    var map = new ol.Map({
      layers: [
        new ol.layer.Tile({
          source: new ol.source.OSM({
             url: 'http://your-ip/osm_tiles/{z}/{x}/{y}.png'
     target: 'map',
     controls: ol.control.defaults({
        attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
          collapsible: false
    view: new ol.View({
       center: [244780.24508882355, 7386452.183179816],

  document.getElementById('zoom-out').onclick = function() {
    var view = map.getView();
    var zoom = view.getZoom();
    view.setZoom(zoom - 1);

  document.getElementById('zoom-in').onclick = function() {
     var view = map.getView();
     var zoom = view.getZoom();
     view.setZoom(zoom + 1);

Save and close the file. Now you can view your slippy map by typing your server IP address in browser.

your-ip/index.html           or          your-ip


To display your slippy map with Leftlet, first create a web folder.

sudo mkdir /var/www/osm

Then download JavaScript and CSS from and extract it to the web root folder.

Next, create the index.html file.

sudo nano /var/www/osm/index.html

Paste the following HTML code in the file. Replace red-colored text and adjust the longitude, latitude and zoom level according to your needs.

<title>My first osm</title>
<link rel="stylesheet" type="text/css" href="leaflet.css"/>
<script type="text/javascript" src="leaflet.js"></script>

  <div id="map"></div>
    var map ='map').setView([53.555,9.899],5);

Save and close the file. Now you can view your slippy map by typing your server IP address in browser.

your-ip/index.html           or          your-ip
openstreetmap tile server with leaflet

To pre-render tiles instead of rendering on the fly, use render_list command. Pre-rendered tiles will be cached in /var/lib/mod_tile directory. -z and -Z flag specify the zoom level.

render_list -m default -a -z 0 -Z 10

This tutorial is made available with the help from Miles B. Dyson.

Rate this tutorial
[Total: 12 Average: 4.6]
  • [email protected]


  • [email protected]

    hello mr guoan

    i follow every step of your tutoriel but i have problem to display maps.

    i download only a area of france:

    when i lauchn my browser

    ( normally i have to see this tile because she’s in the package
    download (limousin-140101.osm.pbf)

    no maps but this text:

    NoResp200: 0
    NoResp304: 0
    NoResp404: 0
    NoResp503: 0
    NoResp5XX: 0
    NoRespOther: 0
    NoFreshCache: 0

    i have results with i try this request:

    psql -d gis -c “select name from planet_osm_point;”

    so i think my database seems works correctly

    thanks a lot for your response

    regards, nicolas

    • Hi, to see the actual tile you should type


      instead of


      The latter contains the information about the tile.

      • [email protected]

        i try this url but i have a 404 error
        Not Found

        The requested URL /osm_tiles/18/131989/93435.png was not found on this server.

        Apache/2.4.18 (Ubuntu) Server at Port 80)

        i follow every steps so i dont know where is the problem

        thanks a lot

        • Can you give the link of your downloaded map? Sorry but you have to use HTML tag to add link in disqus comment system. Directly pasted link will be truncated by disqus.

          I will try to import your map data and see if it will work on my side.

          • [email protected]

            hello mr guoan.

            i re test your tutorial and it works !!

            tanks a lot

            i have a bug because i have to write a new line:

            sudo gpasswd -a username sudo.

            ( perhaps you can add this line for others users)

            i have only 10 giga so i have to take 50giga more but what is the techniq to change the directory of tiles ( with the new 50 giga, its another partition)



  • baditaflorin

    Hi, first of all, thanks for the tutorial, it`s great.

    One question, can you update the tutorial or explain how can we make a self updating OSM tile server so that each day, or each week the map will be updated with the latest changes that appeared in OSM, similar with what OSM site it`s doing now, where if you edit, in 5 minutes you will be able to see the changes.

  • PaulInOttawa

    Thank-you for your recipe! Unfortunately, I’m still running into frustrations with mod_tile .. I had to apt remove g++ to resolve one set of errors, had to apt install libpixman-1-0 to address a second set of errors, and now ‘make’ in mod_tile is giving me libtool warnings and an error, “cannot find the library ‘/home/travis/build/mapbox/mason/mason_packages/linux-x86_64/pixman/0.32.6/lib/’ or unhandled argument ‘/home/travis/build/mapbox/mason/mason_packages/linux-x86_64/pixman/0.32.6/lib/'”

    No idea who travis is, or why his homedir is hardcoded into a path somewhere 🙂

    Any thoughts on what I might do? Or should I run your recipe from a brand-new 16.04 install and hope for better luck?

    • Hi, in the mod_tiles source directory there’s a hidden file named .travis.yml. Maybe you should check it out. And this tutorial is tested on a fresh Ubuntu 16.04 install.

  • Jason

    Hi, Great tutorial! I was able to load in a small .pbf and serve the tiles to my leaflet viewer. I want to add another .pbf to my server and so I tried just doing the osm2pgsql line of Step-4 again, but with the new .pbf file. However when I restart the server (i.e. reboot the virtualmachine that is running it) I don’t see my knew area on the map, just the original one. Is there something else I need to do to load in new tiles?



    Actually I can see it now. I just had to zoom in and wait for a bit so the renderd service could process the request for the new area I was looking at.

  • sun

    I follow your steps, and I got

    renderd.service is not a native service, redirecting to systemd-sysv-install
    Executing /lib/systemd/systemd-sysv-install enable renderd

    when sudo systemctl enable renderd

    did I miss somethings?
    I am new to linux, sorry if I ask stupid question…

    • This is normal. Ubuntu 16.04 use Systemd instead of Sysvinit.

  • borish

    On my ssh-server, I get

    $ curl

    404 Not Found

    Not Found
    The requested URL /osm-tiles/0/0/0.png was not found on this server.

    Apache/2.4.18 (Ubuntu) Server at Port 80

    The syslog shows that renderd is up and running. /var/lib/mod_tile/ is empty.

  • sun

    Thanks! I have made my own osm.
    But there is a problem that I had tried a lot and still not resolved.

    The fonts of Asian region, like China and Japan are squares.
    After searching in google, I found that the problem is about a font, dejavu…
    And I change all three font sets in style.xml

    But still not work.
    Could you help me with this?