Внимание!

Существует docker-версия тайл-сервера, поэтому можно сильно не погружаться в эту инструкцию.

Технические требования (актуально в моем случае)

  • Минимум ОЗУ: 12 Гб
  • CPU: чем больше ядер, тем лучше
  • HDD: Для дампа России и пары стилей 120 Гб SSD

Установка осуществлялась на чистую Ubuntu 1804, размещенную в VirtualBox на контейнере размером 100Гб.
Внимание! При установке Ubuntu я создал пользователя alexander с паролем  '1'. Он же будет использоваться для учетной записи базы PostgreSQL.

Источник:
https://switch2osm.org/manually-building-a-tile-server-18-04-lts/

Обновить репозитории и пакеты

sudo apt-get update
sudo apt-get upgrade
sudo apt install libboost-all-dev git-core tar unzip wget bzip2 build-essential autoconf libtool libxml2-dev libgeos-dev libgeos++-dev libpq-dev libbz2-dev libproj-dev munin-node munin libprotobuf-c0-dev protobuf-c-compiler libfreetype6-dev libtiff5-dev libicu-dev libgdal-dev libcairo-dev libcairomm-1.0-dev apache2 apache2-dev libagg-dev liblua5.2-dev ttf-unifont lua5.1 liblua5.1-dev libgeotiff-epsg curl

Установка сервера базы данных

sudo apt-get install postgresql postgresql-contrib postgis postgresql-10-postgis-2.4 postgresql-10-postgis-scripts

Создаем базу. Логинимся под пользователем postgres

sudo -u postgres -i

Создаем учетку БД с паролем

createuser alexander --pwprompt

Создаем базу данных gis

createdb -E UTF8 -O alexander gis
psql
    \c gis
    CREATE EXTENSION postgis;
    CREATE EXTENSION hstore;
    ALTER TABLE geometry_columns OWNER TO alexander;
    ALTER TABLE spatial_ref_sys OWNER TO alexander;
    \q
    exit

В домашней папке alexander делаем новую папку src:

mkdir ~/src

Установка osm2pgsql

cd ~/src
git clone git://github.com/openstreetmap/osm2pgsql.git
cd osm2pgsql
sudo apt install make cmake g++ libboost-dev libboost-system-dev libboost-filesystem-dev libexpat1-dev zlib1g-dev libbz2-dev libpq-dev libgeos-dev libgeos++-dev libproj-dev lua5.2 liblua5.2-dev
mkdir build && cd build
cmake ..
make
sudo make install

Установка mapnik

sudo apt-get install autoconf apache2-dev libtool libxml2-dev libbz2-dev libgeos-dev libgeos++-dev libproj-dev gdal-bin libmapnik-dev mapnik-utils python-mapnik
python
# Команды:
    import mapnik
    quit()

Установка mod_tile + renderd

cd ~/src
git clone -b switch2osm git://github.com/SomeoneElseOSM/mod_tile.git
cd mod_tile
./autogen.sh
./configure
make
sudo make install
sudo make install-mod_tile
sudo ldconfig

Установка carto

sudo apt install npm nodejs
sudo npm install -g carto
carto -v

Установка стиля Openstreetmap-Carto

cd ~/src
git clone git://github.com/gravitystorm/openstreetmap-carto.git
cd openstreetmap-carto
# Генерация mapnik.xml на основе стиля project.mml
carto project.mml> mapnik.xml

Загрузка данных OSM PBF с сервера https://download.geofabrik.de/russia.html

mkdir ~/data
cd ~/data
wget https://download.geofabrik.de/russia-181224.osm.pbf

Запуск импорта PBF ⇒ база данных gis

osm2pgsql -d gis -U alexander -W --create --slim  -G --hstore --tag-transform-script ~/src/openstreetmap-carto/openstreetmap-carto.lua -C 2500 --number-processes 1 -S ~/src/openstreetmap-carto/openstreetmap-carto.style ~/data/russia-181224.osm.pbf

Загрузка шейпфайлов для границ стран/регионов в низком зуме

cd ~/src/openstreetmap-carto
scripts/get-shapefiles.py

Установка шрифтов

sudo apt-get install fonts-noto-cjk fonts-noto-hinted fonts-noto-unhinted ttf-unifont

Правим конфиг рендерера

vi /usr/local/etc/renderd.conf
# Вносим изменения:
    XML=~/openstreetmap-carto/src/openstreetmap-carto/mapnik.xml

Подготовка Apache

sudo mkdir /var/lib/mod_tile
sudo chown alexander /var/lib/mod_tile
sudo mkdir /var/run/renderd
sudo chown alexander /var/run/renderd

# Правим файл /etc/apache2/conf-available/mod_tile.conf (создаем при необходимости)
# Текст в файле:
    LoadModule tile_module /usr/lib/apache2/modules/mod_tile.so

sudo a2enconf mod_tile

# Правим файл /etc/apache2/sites-available/000-default.conf
# Добавьте строки между "ServerAdmin" и "DocumentRoot":
    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

# Дважды перегружаем сервис Apache
sudo service apache2 reload
sudo service apache2 reload

Подготовка renderd

#Пробуем ручной запуск renderd
renderd -f -c /usr/local/etc/renderd.conf

# Идем на адрес (IP укажите свой) http://192.168.0.72/hot/0/0/0.png
# Если тайл появился - то все хорошо. Жмите CTRL+C для останова рендререра.

# Правим файл ~/src/mod_tile/debian/renderd.init
    RUNASUSER=alexander

sudo cp ~/src/mod_tile/debian/renderd.init /etc/init.d/renderd
sudo chmod u+x /etc/init.d/renderd
sudo cp ~/src/mod_tile/debian/renderd.service /lib/systemd/system/

# Пробуем запустить сервис renderd
sudo /etc/init.d/renderd start

# Ставим в автозапуск
sudo systemctl enable renderd

Подготовка HTML-файла для просмотра тайлов

# Забираем на машину с браузером файл ~/src/mod_tile/extra/sample_leaflet.html
# Меняем в нем адрес 127.0.0.1 на нужный и открываем полученный HTML-файл в браузере

Дополнение 1. Обновление или дублирование данных OSM

Создать новую базу с названием типа osmcarto_gis20181205 по инструкции  выше. Импортировать туда новый дамп. Скопировать папку стиля в другое  место, например в

/home/alexander/src/openstreetmap-carto-new/

Сменить владельца новой папки на alexander:

sudo chown alexander /home/alexander/src/openstreetmap-carto-new/

Исправить имя базы данных в файле project.mml:

    dbname: "osmcarto_gis20181205"

Генерация нового файла стиля Mapnik:

cd /home/alexander/src/openstreetmap-carto-new/
sudo rm mapnik.xml
carto project.mml> mapnik.xml

Исправить /usr/local/etc/renderd.conf. Дописать в него новый блок:

    [ajt2]
    URI=/hot2/
    TILEDIR=/var/lib/mod_tile
    XML=/home/alexander/src/openstreetmap-carto-new/mapnik.xml
    HOST=localhost
    TILESIZE=256
    MAXZOOM=20

Перезапуск сервисов

sudo service apache2 restart
sudo service renderd restart

Копируем файл sample_leaflet.html > sample_leaflet2.html. Заменить в нем URL на такой:

http://192.168.0.72/hot2/{z}/{x}/{y}.png

Дополнение 2. Добавляем редактор стилей kosmtik

Источники:
https://github.com/kosmtik/kosmtik
Еще интересная ссылка: https://ircama.github.io/osm-carto-tutorials/kosmtik-ubuntu-setup/
Описание CartoCSS: https://media.readthedocs.org/pdf/cartocss/latest/cartocss.pdf

Резервная копия стиля.
Стиль (/home/alexander/src/openstreetmap-carto)  предварительно скопирован в папку  (/home/alexander/src/openstreetmap-carto-new)

cp -r /home/alexander/src/openstreetmap-carto/ /home/alexander/src/openstreetmap-carto-new/
sudo npm -g install kosmtik

# Открытие порта на интерфейсе 192.168.0.72
kosmtik serve /home/alexander/src/openstreetmap-carto-new/project.mml --host 192.168.0.72

# Проходим на URL: http://192.168.0.72:6789/
# Вручную правим файлы *.mss в папке проекта. При сохранении файлов будет автоматически перезапускаться mapnik в составе kosmtik и будут обновляться тайлы в редакторе.

Дополнение 3. Импорт стиля OSM Bright

Источники:
https://github.com/mapbox/osm-bright
https://switch2osm.org/serving-tiles/manually-building-a-tile-server-14-04/
https://github.com/mapbox/osm-bright/blob/master/README.md
По поводу замены в файле osm-bright.osm2pgsql.mml ссылок URL на уже скачанные и распакованные архивы:
https://switch2osm.org/?s=loading+osm+data

Под пользователем postgres создаем базу osmbright_svo_20181210

sudo -u postgres -i
createdb -E UTF8 -O alexander osmbright_svo_20181210

psql
    \c osmbright_svo_20181210
    CREATE EXTENSION postgis;
    CREATE EXTENSION hstore;
    ALTER TABLE geometry_columns OWNER TO alexander;
    ALTER TABLE spatial_ref_sys OWNER TO alexander;
    \q
    exit

Загрузка репозитория стиля и дополнительных данных для низкого зума

cd ~/src
git clone git://github.com/mapbox/osm-bright.git
cd osm-bright
mkdir shp
cd shp
wget http://data.openstreetmapdata.com/simplified-land-polygons-complete-3857.zip
wget http://data.openstreetmapdata.com/land-polygons-split-3857.zip
wget http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_populated_places.zip

# Распаковать архивы в папки с их названиями (без вложенных папок)

Импорт данных в БД

osm2pgsql -c -G -U alexander -W --number-processes 4 -d osmbright_svo_20181210 /home/alexander/data/RU-SVE.pbf
# Другая версия запуска импортера на примере импорта России:
# osm2pgsql --create --cache 3072 --slim --multi-geometry --username alexander --password --number-processes 4 --database osmbright_russia_2018-12-05 /home/alexander/data/russia-181205.osm.pbf
# Такой импорт занял 31027 секунд для России на SSD VirtualBox (MaxWriteSpeed=120Mb/s)
# Здесь важен ключ --cache 3072 :
# - он выделяет 3 Гб ОЗУ для кэша нодов при импорте - значительно ускоряет процесс импорта
# - рекомендуется давать на кэш максимально возможное значение памяти из доступной (80-90%)

Конфигурирование стиля

cd /home/alexander/src/osm-bright/
cp configure.py.sample configure.py

# Приведем конфиг (/home/alexander/src/osm-bright/configure.py) к виду:
    config["name"] = "OSM Bright SvObl"
    config["importer"] = "osm2pgsql"
    config["path"] = path.expanduser("/home/alexander/src/osm-bright")
    config["postgis"]["host"]     = "127.0.0.1"
    config["postgis"]["port"]     = "5432"
    config["postgis"]["dbname"]   = "osmbright_svo_20181210"
    config["postgis"]["user"]     = "alexander"
    config["postgis"]["password"] = "1"

./make.py
cd OSMBrightSvObl
carto project.mml> mapnik.xml

Добавляем новый блок в конфиг рендерера

#  В файле /usr/local/etc/renderd.conf:
    [ajt3]
    URI=/hot3/
    TILEDIR=/var/lib/mod_tile
    XML=/home/alexander/src/osm-bright/OSMBrightSvObl/mapnik.xml
    HOST=localhost
    TILESIZE=256
    MAXZOOM=20

Остановка сервиса renderd, чтобы запустить его вручную…

sudo service apache2 restart
sudo service renderd stop
renderd -f -c /usr/local/etc/renderd.conf

# Делаем новый HTML-файл, проверяем, рендерятся ли тайлы при ручном запуске рендерера.
# Если все хорошо - то запускаем сервис:
sudo service renderd start

Если нужно редактировать стиль:

# Редактор для OSM-Bright
kosmtik serve /home/alexander/src/osm-bright/OSMBrightSvObl/project.mml --host 192.168.0.72

Дополнение 4. Пре-рендеринг тайлов по слоям

Наблюдать за процессом можно так:

tail -F /var/log/syslog

Файлы считал командной ncdu.
Запуск пре-рендеринга для указанных слоев по всей планете:

time render_list -a -n 3 -s /var/run/renderd/renderd.sock -z 11 -Z 11 -m osmbright_scale2_russia
# time - просто таймер для вычисления потраченного времени
# -n - число потоков отправки заданий на рендеринг
# -z -Z - минимальный и максимальный уровень зума для рендеринга
# -m - название блока параметров в файле /usr/local/etc/renderd.conf (в квадратных скобках)

Для пре-рендеринга нужных зон можно использовать такую утилиту-прокладку для render_list

# Источник: https://github.com/alx77/render_list_geo.pl
# Например, Свердловская область даст такие координаты (LAT,LON):
# 62.2, 56.9                        62.2, 66.3
# 55.7, 56.9                        55.7, 66.3

# Команда:
time ./render_list_geo.pl -n 3 -z 0 -Z 16 -x 56.9 -X 66.3 -y 55.7 -Y 62.2 -m osmbright_scale2_russia

Дополнение 5. Добавление на слой OSM-Bright номеров домов

Нужно уже иметь собранную папку стиля (она появляется после запуска ./make.py). Добавляем в папку файл addressing.mss:

/* Features related to (postal) adresses: */
@address-color: #666;

@water-color: #aad3df;
@land-color: #f2efe9;
@standard-halo-radius: 1;
@standard-halo-fill: rgba(255,255,255,0.6);

#interpolation {
  [zoom>= 17] {
    line-color: @address-color;
    line-width: 1;
    line-dasharray: 2,4;
  }
}

#addresses {

  [zoom>= 17] {
    text-name: "[addr_housename]";
    ["addr_housenumber" != null] {
      text-name: [addr_housenumber];
      ["addr_housename" != null] {
        text-name: [addr_housenumber] + "\n" + [addr_housename];
      }
    }
    text-placement: interior;
    //text-face-name: @book-fonts;
    text-face-name: @sans;
    text-fill: @address-color;
    text-halo-radius: @standard-halo-radius;
    text-halo-fill: @standard-halo-fill;
    text-size: 15;
    text-wrap-width: 30; // 3.0 em
    text-line-spacing: -1.5; // -0.15 em
    text-margin: 3; // 0.3 em

    [zoom>= 18] {
      text-halo-radius: @standard-halo-radius * 1.25;
      text-size: 18;
    }

    [zoom>= 20] {
        text-size: 20;
        text-wrap-width: 22; // 2.0 em
        text-line-spacing: -1.65; // -0.15 em
        text-margin: 3.3; // 0.3 em
    }
  }
}

Добавить в файл project.mml изменения:

# Добавить ссылку на addressing.mss, должно получиться так:

  "Stylesheet": [
    "palette.mss",
    "base.mss",
    "roads.mss",
    "labels.mss",
    "addressing.mss"
  ],

# Добавить источник данных для слоя addresses, скорректировать поля подключения к БД,
# примерно вот так:

    {
      "Datasource": {
        "dbname": "osmbright_russia_2018-12-05",
        "extent": "-20037508.34,-20037508.34,20037508.34,20037508.34",
        "geometry_field": "way",
        "host": "127.0.0.1",
        "id": "addresses",
        "key_field": "",
        "password": "1",
        "port": "5432",
        "project": "foss4g-2011",
        "srs": "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over",
        "table": "(SELECT
            way,
            \"addr:housenumber\" AS addr_housenumber,
            \"addr:housename\" AS addr_housename,

            way_area/NULLIF(!pixel_width!::real*!pixel_height!::real,0) AS way_pixels
          FROM planet_osm_polygon
          WHERE ((\"addr:housenumber\" IS NOT NULL) OR (\"addr:housename\" IS NOT NULL) )
            AND building IS NOT NULL
        UNION ALL
        SELECT
            way,
            \"addr:housenumber\" AS addr_housenumber,
            \"addr:housename\" AS addr_housename,
            NULL AS way_pixels
          FROM planet_osm_point
          WHERE (\"addr:housenumber\" IS NOT NULL) OR (\"addr:housename\" IS NOT NULL)
          ORDER BY way_pixels DESC NULLS LAST) AS DATA \n",
        "type": "postgis",
        "user": "alexander"
      },
      "advanced": {},
      "class": "",
      "extent": [
        -122.85990918289764,
        47.38001179491598,
        -121.86970418303555,
        47.842970094896586
      ],
      "geometry": "point",
      "id": "addresses",
      "name": "addresses",
      "srs": "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over",
      "srs-name": "900913"
    }

Сгенерировать новый стиль для Mapnik

carto project.mml> mapnik.xml

Трики

Если будут проблемы с подключением к базе, то может пригодиться:

# Добавил строчку в конфиг /etc/postgresql/10/main/pg_hba.conf:
    host<-->all<---><------>all<---><------>192.168.0.0/24<><------>md5

# Добавил строчку в /etc/postgresql/10/main/postgresql.conf
    listen_addresses = '*'

Если забыли указать пароль при создании учетки postgres, то вот:

sudo -u postgres psql
    ALTER USER alexander PASSWORD '1';
    \q
   

Если устал ждать, пока запарсится дамп PBF в базу Pgsql, то можно  прикинуть, сколько осталось ждать, натравив на дамп PBF такую утилиту:

# Взято отсюда: https://gis.stackexchange.com/questions/238009/get-the-date-information-of-a-pbf-file
# https://wiki.openstreetmap.org/wiki/Osmconvert
osmconvert64-0.8.8p.exe l:\opt\_osm-dumps\0.4.0\2018-12-05\russia-181205.osm.pbf --out-statistics
Она выведет объем данных в дампе по типам Node/Way/Relation.
После того, как прикинули по времени, еще умножьте на 2 или 3, т.к. будет произведена индексация загруженных данных.

Добавление недостающих шрифтов

https://askubuntu.com/questions/3697/how-do-i-install-fonts
http://tile.paulnorman.ca/fonts/Malige-n.ttf
https://www.dafontfree.net/freefonts-unifont-f165343.htm
https://github.com/saiswa/free-fonts/tree/master/PCLinuxOSFonts

# Скачать шрифт TTF (например, ArundinaSans.ttf), положить его в папку /usr/share/fonts/truetype
# Обновить кэш шрифтов:
fc-cache -f -v
# Убедиться, что шрифт подключен:
fc-list | grep Arund

Для включения режима увеличения текста в тайлах

В файле /usr/local/etc/renderd.conf добавить в нужную секцию параметр:
SCALE=2

Для отключения перегенерации тайлов (следует проверить дополнительно)

# Взято отсюда: https://forum.openstreetmap.org/viewtopic.php?id=52795
# В файле
#    /etc/apache2/sites-enabled/000-default.conf
#    в блоке <VirtualHost *:80> добавить строку:
#        ModTileBulkMode On
# и перезапустить сервис апача

Для добавления swap на Ubuntu 1804 (если памяти все-таки не хватило)

Swap в Ubuntu 1804 может быть добавлен в виде файла, не требуется переразметка разделов диска.
https://askubuntu.com/questions/1075505/how-do-i-increase-swapfile-in-ubuntu-18-04