Ручная сборка тайл-сервера (16.04.2 LTS)
На этой странице рассказывается, как установить и настроить все необходимое программное обеспечение для работы собственного тайл-сервера. Пошаговая инструкция написаны для Ubuntu Linux 16.04.2 LTS (Xenial Xerus).
Установка программного обеспечения
Тайл-сервер - это набор определенных программ и библиотек, которые взаимодействуя между собой обеспечивают генерацию тайлов и их предоставление пользователям. Как это распространено в мире OpenStreetMap, существует несколько различных конфигураций тайл-серверов, так как почти у всех инструментов есть альтернативы со своими плюсами и минусами. Данное руководство описывает запуск наиболее стандартного тайл-сервара, аналогичного тому, который используется на серверах OpenStreetMap.org.
Тайл-сервер - это пять основных компонентов: mod_tile, renderd, mapnik, osm2pgsql и база данных postgresql/postgis. Mod-tile - это модуль Apache, который проверяет наличие тайла и его актуальность. Если тайл устарел, то модуль запрашивает его обновление. Renderd - утилита, обеспечивающая формирование приоритетной очереди различных типов запросов для управления и сглаживания нагрузки от запросов на рендеринг. Mapnik - библиотека, которая собственно и генерирует (рендерит) тайлы, согласно очереди предоставленной ей Renderd.
Обратите внимание, что данная инструкция была написана и протестирована на вновь установленном сервере Ubuntu 16.04. Если у вас уже установлены другие версии некоторых программ (возможно, вы обновились с более ранней версии Ubuntu, или вы настроили загрузку некоторых PPA), то вам, возможно, потребуется внести некоторые изменения.
Для того, чтобы установить эти компоненты, необходимо сначала установить различные зависимости:
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 libpng12-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
Эта операция займет некоторое время, так что можно даже успеть выпить чашку чая. Этот список включает в себя различные утилиты и библиотеки, например, веб-сервер Apache и “carto“, который используется для преобразования таблиц стилей Carto-CSS в то, что ”mapnik” уже может потом использовать при генерации (рендеринге) тайлов. Когда установка завершится, установите второй набор необходимых компонентов:
Установка postgresql / postgis
В Ubuntu есть готовые версии как postgis, так и postgresql, поэтому их можно просто установить с помощью менеджера пакетов Ubuntu.
sudo apt-get install postgresql postgresql-contrib postgis postgresql-9.5-postgis-2.2
“postgresql“ - это база данных, в которой мы будем хранить данные карты, а ”postgis” добавляет к ней дополнительную географическую поддержку.
Теперь вам нужно создать базу данных Postgis. По умолчанию различные программы предполагают, что база данных называется gis. Мы тоже будем использовать в своей инструкции такое же название, хотя в этом нет никакой необходимости. Вы должны указать свое имя пользователя вместо “renderaccount”, где оно используется ниже. Это должно быть имя пользователя, который будет генерировать тайлы с помощью Mapnik.
sudo -u postgres -i
createuser renderaccount # answer yes for superuser (although this isn't strictly necessary)
createdb -E UTF8 -O renderaccount gis
Пока вы всё ещё работаете от имени пользователя “postgres”, установите PostGIS на базу PostgreSQL (опять же, заменив renderaccount на своё имя пользователя):
psql
(вы увидите приглашение “postgres=#”)
\c gis
(в ответ вы получите “You are now connected to database ‘gis’ as user ‘postgres’”)
CREATE EXTENSION postgis;
(в ответ вы получите “CREATE EXTENSION”)
CREATE EXTENSION hstore;
(в ответ вы получите “CREATE EXTENSION”)
ALTER TABLE geometry_columns OWNER TO renderaccount;
(в ответ вы получите “ALTER TABLE”)
ALTER TABLE spatial_ref_sys OWNER TO renderaccount;
(в ответ вы получите “ALTER TABLE”)
\q
(при этом вы выйдите из psql и вернётесь к обычной командной строке Linux)
exit
(чтобы вернуться к пользователю, под которым вы работали до команды “sudo -u postgres -i”)
Если вы ещё не создали, то также создайте Unix-пользователя с соответствующим именем, введя пароль по запросу:
sudo useradd -m renderaccount
sudo passwd renderaccount
Опять же, замените “renderaccount” на то имя пользователя (не root), которое вы ранее выбрали.
Установка osm2pgsql
Часть программного обеспечения необходимо собрать из исходников. Первое из них - это “osm2pgsql”. Есть разные инструменты для импорта и управления данными OpenStreetMap в базах данных, но мы будем использовать именно этот, так как он наиболее популярный.
mkdir ~/src
cd ~/src
git clone git://github.com/openstreetmap/osm2pgsql.git
cd osm2pgsql
Механизм сборки 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
Опять же, ответьте yes для установки.
mkdir build && cd build
cmake ..
(Вывод этих команд должен закончится сообщениями “build files have been written to”)
make
(Эта команда должна завершиться сообщением “[100%] Built target osm2pgsql”)
sudo make install
Mapnik
Далее устанавливаем Mapnik. Мы будем использовать ту версию, которая идет по умолчанию в Ubuntu Ubuntu 16.04:
sudo apt-get install autoconf apache2-dev libtool libxml2-dev libbz2-dev libgeos-dev libgeos++-dev libproj-dev gdal-bin libgdal1-dev libmapnik-dev mapnik-utils python-mapnik
Проверим, правильно ли установился Mapnik:
python
>>> import mapnik
>>>
Если python в ответ снова выводит приглашение »> без ошибок, значит, библиотека Mapnik найдена Python. Поздравляем! Вы можете выйти из Python с помощью команды:
>>> quit()
Установка mod_tile и renderd
Далее мы установим mod_tile и renderd. “mod_tile” - это модуль Apache, который обрабатывает запросы на тайлы. “renderd” - это фоновая программа, которая фактически генерирует (рендерит) тайлы, когда “mod_tile” запрашивает их. Мы будем использовать форк “mod_tile” - “switch2osm”, который модифицирован для Ubuntu 16.04 и использованию на стандартном сервере Ubuntu, а не на одном из серверов генерации (рендеринга) OSM.
Компиляция mod_tile из исходников:
cd ~/src
git clone -b switch2osm git://github.com/SomeoneElseOSM/mod_tile.git
cd mod_tile
./autogen.sh
(в конце вы должны получить “autoreconf: Leaving directory ‘.’”.)
./configure
(в конце вы должны получить “config.status: executing libtool commands”)
make
Обратите внимание, что на этом этапе будут выскакивать некоторые “предупреждающие” сообщения. Тем не менее, всё должно закончиться сообщением “make[1]: Leaving directory ‘/home/renderaccount/src/mod_tile’”.
sudo make install
(Это должно закончиться сообщением “make[1]: Leaving directory ‘/home/renderaccount/src/mod_tile’”)
sudo make install-mod_tile
(Это должно закончиться сообщением “chmod 644 /usr/lib/apache2/modules/mod_tile.so”)
sudo ldconfig
(Тут не должно быть никаких сообщений)
Настройка таблицы стилей
Теперь, когда все необходимое программное обеспечение установлено, вам нужно будет скачать и настроить таблицу стилей.
Мы будем использовать тот же самый картостиль, который вы можете увидеть на сайте openstreetmap.org. Выбор обусловлен тем, что он достаточно хорошо задокументирован и работает практически в любой точки мира, в том числе и в местах с нелатинскими названиями. Однако у него есть несколько недостатков. Главные из которых - это предельная усредненность для работы в глобальном масштабе, также в нем довольно сложно разобраться и оперативно модифицировать в случае необходимости.
Несмотря на то, что у “OpenStreetMap Carto” есть свой домашний сайт и собственные инструкции по установке, все же мы расскажем, что необходимо сделать для его настройки.
Предполагается, что мы разместим файлы стиля в подкаталоге src домашней директории пользователя “renderaccount” (или какое там вы использовали).
cd ~/src
git clone git://github.com/gravitystorm/openstreetmap-carto.git
cd openstreetmap-carto
Далее установим подходящую версию компилятора carto. Она новее, чем версия, идущая вместе с Ubuntu, так что нам необходимо сделать следующее:
sudo apt install npm nodejs-legacy
sudo npm install -g carto
carto -v
В ответ мы получем значение, которое должно быть не меньше, чем:
carto 0.18.1 (Carto map stylesheet compiler)
Затем преобразуем проект carto в то, что понимает Mapnik:
carto project.mml > mapnik.xml
Теперь у вас есть XML-стиль Mapnik в файле /home/renderaccount/src/openstreetmap-carto/mapnik.xml.
Загрузка данных
В качестве примера мы загрузим небольшой объем тестовых данных. Их можно скачать в разных местах, но “download.geofabrik.de” предлагает весьма широкий выбор. Попробуем, например, скачать Азербайджан (~19 Мб).
Зайдите на страничку “Azerbaijan” на сайте Geofabrik и обратите внимание на дату “This file was modified” (что-то вида “2019-12-22T21:59:02Z”). Нам она потребуется, если мы захотим после обновлять свою базу данных. Скачайте данные по Азербайджану следующим образом:
mkdir ~/data
cd ~/data
wget http://download.geofabrik.de/asia/azerbaijan-latest.osm.pbf
Следующая команда вставит в базу данных скачанные данные из OpenStreetMap. Во время этой операции значительно увеличится нагрузка на жесткий диск. Импорт всей планеты может занять несколько часов, дней или даже недель в зависимости от мощности вашего оборудования. Небольшие выгрузки, конечно, импортируются значительно быстрее, но в любом случае вам может потребоваться поэкспериментировать с различными значениями -C, чтобы уместиться в доступную оперативную память вашего сервера.
osm2pgsql -d gis --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/azerbaijan-latest.osm.pbf
Полезно пояснить, что означают эти опции:
-d gis
База данных, с которой мы работаем (“gis” использовалась по умолчанию, но теперь это надо указывать)
--create
Загрузить данные в пустую базу вместо того, чтобы пытаться дополнить уже имеющиеся.
--slim
osm2pgsql может использовать различные схемы таблиц, “slim” подходит для рендеринга.
-G
Указывает, как обрабатывать мультиполигоны.
--hstore
Позволяет использовать для рендеринга тэги, для которых нет отдельных колонок в базе данных.
--tag-transform-script
Указывает на lua-скрипт, используемый при обработке тэгов. Это простейший способ обрабатывать тэги OSM до того, как они будут обработаны с помощью style-файла, чтобы сделать логику стиля потенциально проще.
-C 2500
Выделяет 2,5 Гб оперативной памяти для osm2pgsql на процесс импорта. Если у вас недостаточно памяти, вы можете попробовать уменьшить это значение, а если процесс импорта будет убит из-за нехватки памяти, вам потребуется уменьшить это число или попробовать выгрузку OSM меньшего объёма.
--number-processes 1
Использует один процесс. Если у вас есть больше процессорных ядер, вы можете указать больше.
-S
Создаёт колонки в базе данных, как указано в этом файле (в данном случае они не будут отличаться от “openstreetmap-carto”)
Последним параметром указан файл для загрузки.
Команда завершится сообщением навроде “Osm2pgsql took 238s overall”.
Загрузка shape-файла
Несмотря на то, что практически вся необходимая информация для генерации тайлов берётся непосредственно из выгрузки OpenStreetMap, которую вы скачали чуть ранее, все же потребуются некоторые shape-файлы, такие, как границы государств для низких масштабных уровней. Чтобы скачать и проиндексировать их:
cd ~/src/openstreetmap-carto/
scripts/get-shapefiles.py
Этот процесс предполагает скачивание значительного объема информации с интернета и может занять какое-то время. По завершении он должен сообщить “…script completed.”
Шрифты
Названия, используемые для обозначения мест по всему миру, не всегда пишутся латинскими буквами (обычный алфавит “a”-“z”). Для установки необходимых шрифтов сделайте следующее:
sudo apt-get install fonts-noto-cjk fonts-noto-hinted fonts-noto-unhinted ttf-unifont
В инструкции, написанной разработчиками OpenSteetMap Carto, также предлагается установить из исходного кода “Noto Emoji Regular”. Но он может пригодиться только для отображения эмодзи в названиях американских магазинов. Все другие международные шрифты, которые могут понадобиться в работе (в том числе те, которые часто не поддерживаются), включены в список только что установленных.
Настройка вашего веб-сервера
Настраиваем renderd
Конфиг для “renderd” находится в файле “/usr/local/etc/renderd.conf”. Отредактируйте его с помощью текстового редактора, например, nano:
sudo nano /usr/local/etc/renderd.conf
Потребуется изменить несколько строк. В секции “renderd”:
num_threads=4
Если у вас только 2 Гб памяти или около того, вы можете захотеть уменьшить это значение до 2.
Секция “ajt” соответствует картостилю с именем “ajt”. У вас может быть более одной такой секции, использующей разные URI для каждой. Строку “XML” следует изменить на что-то вроде:
XML=/home/renderaccount/src/openstreetmap-carto/mapnik.xml
Вы можете изменить “renderaccount” на имя того не-root-пользователя, что использовали выше.
URI=/hot/
Это выбрано для того, чтобы сгенерированные тайлы, можно было проще использовать заместо слоя HOT на сайте OpenStreetMap.org. Вы можете написать тут что-то ещё, но /hot тоже неплохо.
Настраиваем Apache
sudo mkdir /var/lib/mod_tile
sudo chown renderaccount /var/lib/mod_tile
sudo mkdir /var/run/renderd
sudo chown renderaccount /var/run/renderd
Вы теперь должны сказать Apache о модуле mod_tile, для чего с помощью nano (или другого редактора)
sudo nano /etc/apache2/conf-available/mod_tile.conf
добавьте в файл следующую строку:
LoadModule tile_module /usr/lib/apache2/modules/mod_tile.so
затем сохраните его и выполните:
sudo a2enconf mod_tile
Вы получите сообщение, что необходимо выполнить “service apache2 reload” для активации новой конфигурации, но пока этого делать не нужно.
Теперь надо рассказать Apache про “renderd”. С помощью nano (или иного редактора)
sudo nano /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
(Почему это нужно сделать два раза? Подозреваю, что Apache слегка “тупит”, когда перенастраивается, будучи запущенным).
Если вы откроете в web-браузере адрес http://адрес-вашего-сервера/index.html, то должны увидеть страницу Ubuntu/Apache “It work!”
(Если вы не знаете выданный серверу IP-адрес, то вы можете, скорее всего, можете использовать ifconfig чтобы узнать - если только конфигурации сети не является чересчур сложной - адрес должен быть в строке “inet addr”, но не “127.0.0.1”). Если вы используете сервер у хостинг-провайдера, то, возможно, что внутренний адрес сервера будет отличаться от внешнего, выданного вам, но внешний IP уже должен быть у вас и, вероятно, вы уже работаете с сервером именно по этому адресу.
Обратите внимание, что этот сайт работает только по http (порт 80), вам потребуется сделать больше, чтобы включить в Apache https, но это выходит за рамки нашей инструкции. Тем не менее, если вы используете “Let’s Encrypt” для выпуска сертификатов, то процесс настройки его может также настраивать использование https в Apache.
Запускаем renderd первый раз
Теперь мы запустим renderd, чтобы сгенерировать несколько тайлов. Изначально мы запустим его так, чтобы можно было видеть ошибки по мере их появления:
renderd -f -c /usr/local/etc/renderd.conf
Вы можете увидеть несколько предупреждений, пока не обращайте на них внимания. Вам надо не получить ошибок. Если они будут, сохраните полный вывод и через сайт типа pastebin.com сообщите о проблеме где-нибудь, например, на help.openstreetmap.org (дайте ссылку на pastebin.com - не включайте весь текст в вопрос).
Введите в своем браузере следующий адрес: http://адрес-вашего-сервера/hot/0/0/0.png
Вы должны увидеть карту всего мира в браузере и отладочную информацию в консоли, в том числе сообщения “DEBUG: START TILE” и “DEBUG: DONE TILE”. Игнорируйте “DEBUG: Failed to read cmd on fd” - это не ошибки. Если вы не получили изображение тайла или получили какие-либо ошибки - снова сохраните их в pastebin и задайте вопрос где-нибудь на help.openstreetmap.org.
Если все работает, нажмите CTRL-C, чтобы завершить приложение рендеринга.
Запуск renderd в фоновом режиме
Далее мы настроим “renderd” для запуска в фоновом режиме. Для начала, отредактируйте файл “~/src/mod_tile/debian/renderd.init” и укажите в качестве RUNASUSER того не-root-пользователя типа “renderaccount”, которым вы использовали ранее, далее скопируйте файл в системную директорию:
nano ~/src/mod_tile/debian/renderd.init
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.service” - это файл сервиса “systemd”. Используемая тут версия просто вызывает старые init-команды. Чтобы убедиться, что команда start работает, выполните:
sudo /etc/init.d/renderd start
(должно вывести “[ ok ] Starting renderd (via systemctl): renderd.service”.)
Чтобы он всегда запускался автоматически:
sudo systemctl enable renderd
Просмотр тайлов
Чтобы увидеть тайлы, воспользуемся хитрым расширением “Switcheroo Redirector” для Chrome (или Chromium):
https://chrome.google.com/webstore/detail/switcheroo-redirector/cnmciclhnghalnpfhhleggldniplelbg?hl=en
Добавим “https://tile-a.openstreetmap.fr/hot/” как “From” и “http://your.server.ip.address/hot/” как “To”, аналогично для “tile-b” и “tile-c”.
Из ssh-соединения запустите:
tail -f /var/log/syslog | grep " TILE "
(обратите внимание, что тут есть пробелы вокруг “TILE”)
Эта команда будет выводить строку каждый раз, когда тайл запрашивается, а также когда рендеринг тайла завершится.
В вашем Chrome/Chromium с настроенным Switcheroo откройте: http://www.openstreetmap.org/#map=13/40.3743/49.7134
и выберите слой “Humanitarian”. Когда вы будете загружать страницу, то должны будете увидеть, как поступают запросы на тайлы. Постепенно уменьшайте масштаб и вы увидите, что запросы на новые тайлы появляются в ssh-соединении. Генерация некоторых тайлов с нуля с низким масштабированием может занять достаточно времени (несколько минут), но зато они быстро загрузятся в следующий раз.
Поздравляем! Теперь вам нужно ознакомиться с разделом “Тайлы”, чтобы сделать карту, которая бы использовала ваш новый тайл-сервер.