2 # Cookbook:: vectortile
5 # Copyright:: 2024, OpenStreetMap Foundation
7 # Licensed under the Apache License, Version 2.0 (the "License");
8 # you may not use this file except in compliance with the License.
9 # You may obtain a copy of the License at
11 # https://www.apache.org/licenses/LICENSE-2.0
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS,
15 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
20 include_recipe "accounts"
22 include_recipe "nginx"
23 include_recipe "podman"
24 include_recipe "postgresql"
25 include_recipe "prometheus"
26 include_recipe "python"
27 include_recipe "tools"
29 directory "/srv/vector.openstreetmap.org" do
35 nginx_site "default" do
39 nginx_site "vector.openstreetmap.org" do
43 ssl_certificate node[:fqdn] do
45 notifies :reload, "service[nginx]"
48 remote_directory "/srv/vector.openstreetmap.org/html" do
53 files_owner "www-data"
54 files_group "www-data"
58 template "/srv/vector.openstreetmap.org/html/index.html" do
59 source "index.html.erb"
65 postgresql_version = node[:vectortile][:database][:cluster].split("/").first
66 postgis_version = node[:vectortile][:database][:postgis]
68 package "postgresql-#{postgresql_version}-postgis-#{postgis_version}"
78 style_directory = "/srv/vector.openstreetmap.org/spirit"
79 git style_directory do
80 repository "https://github.com/pnorman/spirit.git"
81 revision node[:vectortile][:spirit][:version]
86 shortbread_config = "#{style_directory}/shortbread.yaml"
88 themepark_directory = "/srv/vector.openstreetmap.org/osm2pgsql-themepark"
89 git themepark_directory do
90 repository "https://github.com/osm2pgsql-dev/osm2pgsql-themepark.git"
91 revision node[:vectortile][:themepark][:version]
96 tilekiln_directory = "/opt/tilekiln"
98 python_virtualenv tilekiln_directory do
99 interpreter "/usr/bin/python3"
102 python_package "tilekiln" do
103 python_virtualenv tilekiln_directory
105 version node[:vectortile][:tilekiln][:version]
108 template "/srv/vector.openstreetmap.org/html/index.html" do
109 source "index.html.erb"
115 directory "/srv/vector.openstreetmap.org/data" do
121 node_store_options = node[:vectortile][:database][:nodes_store] == :flat ? "--flat-nodes '/srv/vector.openstreetmap.org/data/nodes.bin'" : ""
122 template "/usr/local/bin/import-planet" do
123 source "import-planet.erb"
127 variables :node_store_options => node_store_options
130 template "/usr/local/bin/tilekiln-storage-init" do
131 source "tilekiln-storage-init.erb"
135 variables :tilekiln_bin => "#{tilekiln_directory}/bin/tilekiln", :storage_database => "tiles", :config_path => shortbread_config
138 postgresql_user "tomh" do
139 cluster node[:vectortile][:database][:cluster]
143 postgresql_user "pnorman" do
144 cluster node[:vectortile][:database][:cluster]
148 postgresql_user "tilekiln" do
149 cluster node[:vectortile][:database][:cluster]
152 postgresql_user "tileupdate" do
153 cluster node[:vectortile][:database][:cluster]
156 postgresql_database "tiles" do
157 cluster node[:vectortile][:database][:cluster]
161 postgresql_extension "pgstattuple" do
162 cluster node[:vectortile][:database][:cluster]
166 postgresql_database "spirit" do
167 cluster node[:vectortile][:database][:cluster]
171 postgresql_extension "postgis" do
172 cluster node[:vectortile][:database][:cluster]
176 postgresql_schema "tilekiln" do
177 cluster node[:vectortile][:database][:cluster]
180 permissions "tileupdate" => :all, "tilekiln" => :usage
181 notifies :run, "execute[tilekiln-storage-init]", :immediately
184 execute "tilekiln-storage-init" do
186 command "/usr/local/bin/tilekiln-storage-init"
190 %w[metadata shortbread_v1].each do |table|
191 postgresql_table table do
192 cluster node[:vectortile][:database][:cluster]
196 permissions "tileupdate" => :all, "tilekiln" => :select
200 postgresql_table "tile_stats" do
201 cluster node[:vectortile][:database][:cluster]
207 (0..14).each do |zoom|
208 postgresql_table "shortbread_v1_z#{zoom}" do
209 cluster node[:vectortile][:database][:cluster]
213 permissions "tileupdate" => :all, "tilekiln" => node[:vectortile][:serve][:mode] == :live ? [:select, :insert, :update] : :select
217 %w[addresses aerialways aeroways boundaries boundary_labels bridges buildings
218 dam_lines dam_polygons ferries land pier_lines pier_polygons place_labels
219 planet_osm_nodes planet_osm_rels planet_osm_ways pois public_transport railways
220 road_routes roads sites street_polygons street_labels_points
221 streets_polygons_labels water_area_labels water_areas water_lines water_lines_labels].each do |table|
222 postgresql_table table do
223 cluster node[:vectortile][:database][:cluster]
227 permissions "tileupdate" => :all, "tilekiln" => :select
231 tilekiln_mode = node[:vectortile][:serve][:mode] == :live ? "live --config #{shortbread_config} --source-dbname spirit" : "static"
233 systemd_service "tilekiln" do
234 description "Tilekiln vector tile server"
236 after "postgresql.service"
237 wants "postgresql.service"
238 sandbox :enable_network => true
239 restrict_address_families "AF_UNIX"
240 environment "PGAPPNAME" => "tilekiln"
241 exec_start "#{tilekiln_directory}/bin/tilekiln serve #{tilekiln_mode} --storage-dbname tiles --num-threads #{node[:vectortile][:serve][:threads]} --base-url 'https://vector.openstreetmap.org'"
244 service "tilekiln" do
245 action [:enable, :start]
248 template "/usr/local/bin/ocean-update" do
249 source node[:vectortile][:ocean][:tileupdate] ? "ocean-update-tile.erb" : "ocean-update-notile.erb"
253 variables :tilekiln_bin => "#{tilekiln_directory}/bin/tilekiln", :source_database => "spirit", :storage_database => "tiles", :style_directory => style_directory, :config_path => shortbread_config
256 systemd_service "ocean-update" do
257 description "Update ocean data"
259 after "postgresql.service"
260 wants "postgresql.service"
261 sandbox :enable_network => true
262 restrict_address_families "AF_UNIX"
263 read_write_paths ["/srv/vector.openstreetmap.org/spirit/data/"]
264 exec_start "/usr/local/bin/ocean-update"
267 systemd_timer "ocean-update" do
268 description "Update ocean data"
270 on_unit_active_sec 3600
274 if node[:vectortile][:ocean][:enabled]
275 service "ocean-update.timer" do
276 action [:enable, :start]
279 service "ocean-update.timer" do
280 action [:stop, :disable]
284 template "/usr/local/bin/vector-update" do
285 source node[:vectortile][:replication][:tileupdate] ? "vector-update-tile.erb" : "vector-update-notile.erb"
289 variables :tilekiln_bin => "#{tilekiln_directory}/bin/tilekiln", :source_database => "spirit", :config_path => shortbread_config, :diff_size => "1000", :expiry_dir => "/srv/vector.openstreetmap.org/data/", :post_processing => "/usr/local/bin/tiles-rerender"
292 rerender_layers = %w[addresses boundaries bridges buildings land pois public_transport sites street_polygons streets water_lines_labels water_lines water_polygons].join(" ")
294 template "/usr/local/bin/tiles-rerender" do
295 source "tiles-rerender.erb"
299 variables :tilekiln_bin => "#{tilekiln_directory}/bin/tilekiln", :source_database => "spirit", :storage_database => "tiles", :config_path => shortbread_config, :expiry_dir => "/srv/vector.openstreetmap.org/data/", :update_threads => 4, :layers => rerender_layers.to_s
302 systemd_service "replicate" do
303 description "Get replication updates"
305 after "postgresql.service"
306 wants "postgresql.service"
307 sandbox :enable_network => true
308 restrict_address_families "AF_UNIX"
309 read_write_paths ["/srv/vector.openstreetmap.org/data/"]
310 exec_start "/usr/local/bin/vector-update"
313 systemd_timer "replicate" do
314 description "Get replication updates"
316 on_unit_active_sec 30
320 if node[:vectortile][:replication][:enabled]
321 service "replicate.timer" do
322 action [:enable, :start]
325 service "replicate.timer" do
326 action [:stop, :disable]
330 template "/usr/local/bin/render-lowzoom" do
331 source "render-lowzoom.erb"
335 variables :tilekiln_bin => "#{tilekiln_directory}/bin/tilekiln", :source_database => "spirit", :storage_database => "tiles", :config_path => shortbread_config, :min_zoom => 0, :max_zoom => node[:vectortile][:rerender][:lowzoom][:maxzoom]
338 systemd_service "render-lowzoom" do
339 description "Render low zoom tiles"
341 after "postgresql.service"
342 wants "postgresql.service"
343 restrict_address_families "AF_UNIX"
345 exec_start "/usr/local/bin/render-lowzoom"
348 systemd_timer "render-lowzoom" do
349 description "Render low zoom tiles"
350 on_calendar "23:00 #{node[:timezone]}"
353 if node[:vectortile][:rerender][:lowzoom][:enabled]
354 service "render-lowzoom.timer" do
355 action [:enable, :start]
358 service "render-lowzoom.timer" do
359 action [:stop, :disable]
368 prometheus_exporter "osm2pgsql" do
371 restrict_address_families "AF_UNIX"
373 "--database-name=spirit"
377 systemd_service "tilekiln-prometheus" do
378 description "Tilekiln vector tile server"
380 after "postgresql.service"
381 wants "postgresql.service"
382 sandbox :enable_network => true
383 environment "PGAPPNAME" => "tilekiln-prometheus"
384 restrict_address_families "AF_UNIX"
385 exec_start "#{tilekiln_directory}/bin/tilekiln prometheus --bind-host #{node[:prometheus][:address]} --storage-dbname tiles"
388 service "tilekiln-prometheus" do
389 action [:enable, :start]
392 node.default[:prometheus][:exporters][10013] = {
394 :address => "#{node[:prometheus][:address]}:10013",
397 podman_service "vectortile_demo" do
398 description "Container service for /demo pages"
399 image "ghcr.io/openstreetmap/vectortile-website:latest"