diff --git a/docs/assets/nginx.conf b/docs/assets/nginx.conf new file mode 100644 index 0000000..9a108d4 --- /dev/null +++ b/docs/assets/nginx.conf @@ -0,0 +1,619 @@ +user nginx; +pid /var/run/nginx.pid; + + +worker_processes auto; +worker_rlimit_nofile 300000; # needs to be < ulimit -n + +error_log /data/nginx/logs/nginx-error.log warn; + +events { + worker_connections 40000; + multi_accept on; +} + +http { + # aggressive caching for read-only sources + open_file_cache max=1000000 inactive=60m; + open_file_cache_valid 60m; + open_file_cache_min_uses 1; + open_file_cache_errors on; + + server_tokens off; + + include /etc/nginx/mime.types; + types { + application/x-protobuf pbf; + } + default_type application/octet-stream; + + charset utf-8; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + + reset_timedout_connection on; + send_timeout 20; + + max_ranges 0; + + gzip on; + gzip_comp_level 1; + gzip_types application/json application/x-protobuf; + + log_format access_json '{' + + # general + '"time": "$time_iso8601", ' + '"status": $status, ' + #'"request_method": "$request_method", ' + #'"uri": "$uri", ' + #'"request": "$request", ' + #'"request_time": $request_time, ' + '"body_bytes_sent": $body_bytes_sent, ' + '"http_referrer": "$http_referer", ' + '"http_user_agent": "$http_user_agent", ' + #'"scheme": "$scheme", ' + #'"host": "$host", ' + #'"http_host": "$http_host", ' + + # IP address related + # IP address logging is disabled + #'"remote_addr": "$remote_addr", ' + #'"http_x_forwarded_for": "$http_x_forwarded_for", ' + + # CF related + #'"http_cf_ray": "$http_cf_ray", ' + #'"http_cf_ipcountry": "$http_cf_ipcountry", ' + #'"http_cf_connecting_ip": "$http_cf_connecting_ip", ' + + '"_": "_"' # helper for no trailing comma + '}'; + + access_log off; + #access_log /data/nginx/logs/nginx-access.log access_json buffer=128k; + + include /data/nginx/config/*; + include /data/nginx/sites/*; +} + +# configuration file /etc/nginx/mime.types: +types { + + # Data interchange + + application/atom+xml atom; + application/json json map topojson; + application/ld+json jsonld; + application/rss+xml rss; + # Normalize to standard type. + # https://tools.ietf.org/html/rfc7946#section-12 + application/geo+json geojson; + application/xml xml; + # Normalize to standard type. + # https://tools.ietf.org/html/rfc3870#section-2 + application/rdf+xml rdf; + + + # JavaScript + + # Servers should use text/javascript for JavaScript resources. + # https://html.spec.whatwg.org/multipage/scripting.html#scriptingLanguages + text/javascript js mjs; + application/wasm wasm; + + + # Manifest files + + application/manifest+json webmanifest; + application/x-web-app-manifest+json webapp; + text/cache-manifest appcache; + + + # Media files + + audio/midi mid midi kar; + audio/mp4 aac f4a f4b m4a; + audio/mpeg mp3; + audio/ogg oga ogg opus; + audio/x-realaudio ra; + audio/x-wav wav; + image/apng apng; + image/avif avif avifs; + image/bmp bmp; + image/gif gif; + image/jpeg jpeg jpg; + image/jxl jxl; + image/jxr jxr hdp wdp; + image/png png; + image/svg+xml svg svgz; + image/tiff tif tiff; + image/vnd.wap.wbmp wbmp; + image/webp webp; + image/x-jng jng; + video/3gpp 3gp 3gpp; + video/mp4 f4p f4v m4v mp4; + video/mpeg mpeg mpg; + video/ogg ogv; + video/quicktime mov; + video/webm webm; + video/x-flv flv; + video/x-mng mng; + video/x-ms-asf asf asx; + video/x-msvideo avi; + + # Serving `.ico` image files with a different media type + # prevents Internet Explorer from displaying then as images: + # https://github.com/h5bp/html5-boilerplate/commit/37b5fec090d00f38de64b591bcddcb205aadf8ee + + image/x-icon cur ico; + + + # Microsoft Office + + application/msword doc; + application/vnd.ms-excel xls; + application/vnd.ms-powerpoint ppt; + application/vnd.openxmlformats-officedocument.wordprocessingml.document docx; + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx; + application/vnd.openxmlformats-officedocument.presentationml.presentation pptx; + + + # Web fonts + + font/woff woff; + font/woff2 woff2; + application/vnd.ms-fontobject eot; + font/ttf ttf; + font/collection ttc; + font/otf otf; + + + # Other + + application/java-archive ear jar war; + application/mac-binhex40 hqx; + application/octet-stream bin deb dll dmg exe img iso msi msm msp safariextz; + application/pdf pdf; + application/postscript ai eps ps; + application/rtf rtf; + application/vnd.google-earth.kml+xml kml; + application/vnd.google-earth.kmz kmz; + application/vnd.wap.wmlc wmlc; + application/x-7z-compressed 7z; + application/x-bb-appworld bbaw; + application/x-bittorrent torrent; + application/x-chrome-extension crx; + application/x-cocoa cco; + application/x-java-archive-diff jardiff; + application/x-java-jnlp-file jnlp; + application/x-makeself run; + application/x-opera-extension oex; + application/x-perl pl pm; + application/x-pilot pdb prc; + application/x-rar-compressed rar; + application/x-redhat-package-manager rpm; + application/x-sea sea; + application/x-shockwave-flash swf; + application/x-stuffit sit; + application/x-tcl tcl tk; + application/x-x509-ca-cert crt der pem; + application/x-xpinstall xpi; + application/xhtml+xml xhtml; + application/xslt+xml xsl; + application/zip zip; + text/calendar ics; + text/css css; + text/csv csv; + text/html htm html shtml; + text/markdown md markdown; + text/mathml mml; + text/plain txt; + text/vcard vcard vcf; + text/vnd.rim.location.xloc xloc; + text/vnd.sun.j2me.app-descriptor jad; + text/vnd.wap.wml wml; + text/vtt vtt; + text/x-component htc; + +} + +# configuration file /data/nginx/sites/default_disable.conf: +map "" $empty { + default ""; +} + +server { + listen 80 default_server; + listen [::]:80 default_server; + + listen 443 ssl default_server; + listen [::]:443 ssl default_server; + http2 on; + + server_name _; + + ssl_ciphers aNULL; + ssl_certificate /etc/nginx/ssl/dummy.crt; + ssl_certificate_key /etc/nginx/ssl/dummy.key; + + return 444; +} + +# configuration file /data/nginx/sites/ofm_roundrobin.conf: +server { + server_name ofm_roundrobin tiles.openfreemap.org; + + # ssl: https://ssl-config.mozilla.org / intermediate config + + listen 80; + listen 443 ssl; + listen [::]:443 ssl; + http2 on; + + ssl_certificate /data/nginx/certs/ofm_roundrobin.cert; + ssl_certificate_key /data/nginx/certs/ofm_roundrobin.key; + + ssl_session_timeout 1d; + ssl_session_cache shared:MozSSL:10m; # about 40000 sessions + ssl_session_tickets off; + + ssl_dhparam /etc/nginx/ffdhe2048.txt; + + # intermediate configuration + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305; + ssl_prefer_server_ciphers off; + + # access log doesn't contain IP address + access_log off; + #access_log /data/ofm/http_host/logs_nginx/roundrobin-access.jsonl access_json buffer=128k; + + error_log /data/ofm/http_host/logs_nginx/roundrobin-error.log; + + add_header X-Robots-Tag "noindex, nofollow" always; + + + # specific JSON monaco 20250806_231001_pt + location = /monaco/20250806_231001_pt { + # no trailing slash + alias /data/ofm/http_host/runs/monaco/20250806_231001_pt/tilejson-ofm_roundrobin.json; # no trailing slash + + expires 1w; + default_type application/json; + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'specific JSON monaco 20250806_231001_pt'; + } + + # specific PBF monaco 20250806_231001_pt + location ^~ /monaco/20250806_231001_pt/ { + # trailing slash + alias /mnt/ofm/monaco-20250806_231001_pt/tiles/; # trailing slash + try_files $uri @empty_tile; + add_header Content-Encoding gzip; + + expires 10y; + + types { + application/vnd.mapbox-vector-tile pbf; + } + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'specific PBF monaco 20250806_231001_pt'; + } + + # specific JSON planet 20250806_001001_pt + location = /planet/20250806_001001_pt { + # no trailing slash + alias /data/ofm/http_host/runs/planet/20250806_001001_pt/tilejson-ofm_roundrobin.json; # no trailing slash + + expires 1w; + default_type application/json; + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'specific JSON planet 20250806_001001_pt'; + } + + # specific PBF planet 20250806_001001_pt + location ^~ /planet/20250806_001001_pt/ { + # trailing slash + alias /mnt/ofm/planet-20250806_001001_pt/tiles/; # trailing slash + try_files $uri @empty_tile; + add_header Content-Encoding gzip; + + expires 10y; + + types { + application/vnd.mapbox-vector-tile pbf; + } + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'specific PBF planet 20250806_001001_pt'; + } + + # specific JSON monaco 20250805_231001_pt + location = /monaco/20250805_231001_pt { + # no trailing slash + alias /data/ofm/http_host/runs/monaco/20250805_231001_pt/tilejson-ofm_roundrobin.json; # no trailing slash + + expires 1w; + default_type application/json; + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'specific JSON monaco 20250805_231001_pt'; + } + + # specific PBF monaco 20250805_231001_pt + location ^~ /monaco/20250805_231001_pt/ { + # trailing slash + alias /mnt/ofm/monaco-20250805_231001_pt/tiles/; # trailing slash + try_files $uri @empty_tile; + add_header Content-Encoding gzip; + + expires 10y; + + types { + application/vnd.mapbox-vector-tile pbf; + } + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'specific PBF monaco 20250805_231001_pt'; + } + + # specific JSON planet 20250730_001001_pt + location = /planet/20250730_001001_pt { + # no trailing slash + alias /data/ofm/http_host/runs/planet/20250730_001001_pt/tilejson-ofm_roundrobin.json; # no trailing slash + + expires 1w; + default_type application/json; + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'specific JSON planet 20250730_001001_pt'; + } + + # specific PBF planet 20250730_001001_pt + location ^~ /planet/20250730_001001_pt/ { + # trailing slash + alias /mnt/ofm/planet-20250730_001001_pt/tiles/; # trailing slash + try_files $uri @empty_tile; + add_header Content-Encoding gzip; + + expires 10y; + + types { + application/vnd.mapbox-vector-tile pbf; + } + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'specific PBF planet 20250730_001001_pt'; + } + + + # latest JSON monaco + location = /monaco { + # no trailing slash + alias /data/ofm/http_host/runs/monaco/20250806_231001_pt/tilejson-ofm_roundrobin.json; # no trailing slash + + expires 1d; + default_type application/json; + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'latest JSON monaco'; + } + + + # wildcard JSON monaco + location ~ ^/monaco/([^/]+)$ { + # regex location is unreliable with alias, only root is reliable + + root /data/ofm/http_host/runs/monaco/20250806_231001_pt; # no trailing slash + try_files /tilejson-ofm_roundrobin.json =404; + + expires 1w; + default_type application/json; + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'wildcard JSON monaco'; + } + + # wildcard PBF monaco + location ~ ^/monaco/([^/]+)/(.+)$ { + # regex location is unreliable with alias, only root is reliable + + root /mnt/ofm/monaco-20250806_231001_pt/tiles/; # trailing slash + try_files /$2 @empty_tile; + add_header Content-Encoding gzip; + + expires 10y; + + types { + application/vnd.mapbox-vector-tile pbf; + } + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'wildcard PBF monaco'; + } + + + # latest JSON planet + location = /planet { + # no trailing slash + alias /data/ofm/http_host/runs/planet/20250806_001001_pt/tilejson-ofm_roundrobin.json; # no trailing slash + + expires 1d; + default_type application/json; + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'latest JSON planet'; + } + + + # wildcard JSON planet + location ~ ^/planet/([^/]+)$ { + # regex location is unreliable with alias, only root is reliable + + root /data/ofm/http_host/runs/planet/20250806_001001_pt; # no trailing slash + try_files /tilejson-ofm_roundrobin.json =404; + + expires 1w; + default_type application/json; + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'wildcard JSON planet'; + } + + # wildcard PBF planet + location ~ ^/planet/([^/]+)/(.+)$ { + # regex location is unreliable with alias, only root is reliable + + root /mnt/ofm/planet-20250806_001001_pt/tiles/; # trailing slash + try_files /$2 @empty_tile; + add_header Content-Encoding gzip; + + expires 10y; + + types { + application/vnd.mapbox-vector-tile pbf; + } + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'wildcard PBF planet'; + } + + location /fonts/ { + # trailing slash + + alias /data/ofm/http_host/assets/fonts/ofm/; # trailing slash + try_files $uri =404; + + expires 1w; + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + } + + location /natural_earth/ { + # trailing slash + + alias /data/ofm/http_host/assets/natural_earth/ofm/; # trailing slash + try_files $uri =404; + + expires 10y; + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + } + + location /sprites/ { + # trailing slash + + alias /data/ofm/http_host/assets/sprites/; # trailing slash + try_files $uri =404; + + expires 10y; + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + } + + + # we need to handle missing tiles as valid request returning empty string + location @empty_tile { + return 200 ''; + + expires 10y; + + types { + application/vnd.mapbox-vector-tile pbf; + } + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + add_header x-ofm-debug 'empty tile'; + } + + location = / { + return 302 https://openfreemap.org; + } + + + location /styles/ { + # trailing slash + + alias /data/ofm/http_host/assets/styles/ofm/; # trailing slash + try_files $uri.json =404; + + expires 1d; + default_type application/json; + + # substitute the domain in the TileJSON + sub_filter '__TILEJSON_DOMAIN__' 'tiles.openfreemap.org'; + sub_filter_once off; + sub_filter_types '*'; + + add_header 'Access-Control-Allow-Origin' '*' always; + add_header Cache-Control public; + add_header X-Robots-Tag "noindex, nofollow" always; + + } + + # catch-all block to deny all other requests + location / { + deny all; + error_log /data/ofm/http_host/logs_nginx/roundrobin-deny.log error; + } +} +