From 36b1dabefb7fb884d9ffa052f34b0914988e37f5 Mon Sep 17 00:00:00 2001 From: Tobias Date: Mon, 6 Jul 2026 22:30:03 +0200 Subject: [PATCH] reitti: update to v5 --- ct/reitti.sh | 84 +++++++++++++++++++++++++++++++++++---- install/reitti-install.sh | 44 +++++++++++++------- 2 files changed, 106 insertions(+), 22 deletions(-) diff --git a/ct/reitti.sh b/ct/reitti.sh index f160176d4..5980e6ae7 100644 --- a/ct/reitti.sh +++ b/ct/reitti.sh @@ -106,13 +106,6 @@ spring.servlet.multipart.max-file-size=5GB spring.servlet.multipart.max-request-size=5GB server.tomcat.max-part-count=100 -# Rqueue configuration -rqueue.web.enable=false -rqueue.job.enabled=false -rqueue.message.durability.in-terminal-state=0 -rqueue.key.prefix=\${spring.cache.redis.key-prefix} -rqueue.message.converter.provider.class=com.dedicatedcode.reitti.config.RQueueCustomMessageConverter - # Application-specific settings reitti.server.advertise-uri= @@ -168,6 +161,81 @@ PROPEOF msg_ok "Rewrote application.properties (backup: application.properties.bak)" fi + # Migrate v4 -> v5: Remove Rqueue configuration (replaced by Quartz Scheduler) + if grep -q "^rqueue\." /opt/reitti/application.properties 2>/dev/null; then + msg_info "Migrating to v5: Removing Rqueue configuration" + sed -i '/^# Rqueue configuration$/d; /^rqueue\./d' /opt/reitti/application.properties + msg_ok "Removed Rqueue configuration" + fi + + # Migrate v4 -> v5: Update application.properties and nginx tile cache for v5 compatibility + if grep -q "^reitti\.process-data\.schedule=" /opt/reitti/application.properties 2>/dev/null; then + msg_info "Migrating to v5: Updating application.properties" + sed -i '/^reitti\.process-data\.schedule=/d' /opt/reitti/application.properties + sed -i 's/^reitti\.import\.processing-idle-start-time=.*/reitti.import.grace-time-seconds=30/' /opt/reitti/application.properties + sed -i 's/^spring\.datasource\.hikari\.maximum-pool-size=20$/spring.datasource.hikari.maximum-pool-size=30/' /opt/reitti/application.properties + grep -q "devices" /opt/reitti/application.properties || \ + sed -i 's/^spring\.cache\.cache-names=\(.*\)$/spring.cache.cache-names=\1,devices,mapStyles,mapStyleJson/' /opt/reitti/application.properties + grep -q "org.quartz.core.ErrorLogger" /opt/reitti/application.properties || \ + sed -i '/^logging\.level\.com\.dedicatedcode\.reitti=/a logging.level.org.quartz.core.ErrorLogger=FATAL' /opt/reitti/application.properties + grep -q "^spring.servlet.multipart.resolve-lazily=" /opt/reitti/application.properties || \ + sed -i '/^spring\.servlet\.multipart\.max-request-size=/a spring.servlet.multipart.resolve-lazily=true' /opt/reitti/application.properties + grep -q "^spring.mvc.async.request-timeout=" /opt/reitti/application.properties || \ + echo "spring.mvc.async.request-timeout=600000" >>/opt/reitti/application.properties + if ! grep -q "^spring.quartz" /opt/reitti/application.properties; then + cat >>/opt/reitti/application.properties <<'QUARTZEOF' + +# Quartz Scheduler configuration +spring.quartz.job-store-type=jdbc +spring.quartz.jdbc.initialize-schema=never +spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate +spring.quartz.properties.org.quartz.jobStore.isClustered=false +spring.quartz.properties.org.quartz.jobStore.tablePrefix=qrtz_ +spring.quartz.properties.org.quartz.threadPool.threadCount=5 +QUARTZEOF + fi + grep -q "^reitti.import.staging.cleanup.cron=" /opt/reitti/application.properties || \ + echo "reitti.import.staging.cleanup.cron=0 0 4 * * *" >>/opt/reitti/application.properties + grep -q "^reitti.batching.max-batch-size=" /opt/reitti/application.properties || \ + printf "reitti.batching.max-batch-size=100\nreitti.batching.max-wait-time=5\n" >>/opt/reitti/application.properties + grep -q "^reitti.jobs.cleanup.cron=" /opt/reitti/application.properties || \ + printf "reitti.jobs.cleanup.cron=0 0 4 * * ?\nreitti.jobs.cleanup.max-age-hours=24\n" >>/opt/reitti/application.properties + grep -q "^reitti.db-janitor.schedule=" /opt/reitti/application.properties || \ + echo "reitti.db-janitor.schedule=0 0 4 * * ?" >>/opt/reitti/application.properties + msg_ok "Updated application.properties for v5" + + if [[ -f /etc/nginx/nginx.conf ]]; then + msg_info "Migrating to v5: Updating nginx tile cache configuration" + cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.v5 + cat >/etc/nginx/nginx.conf <<'NGINXEOF' +user www-data; + +events { + worker_connections 1024; +} +http { + resolver 1.1.1.1 8.8.8.8 valid=30s ipv6=off; + proxy_cache_path /var/cache/nginx/tiles levels=1:2 keys_zone=tiles:10m max_size=1g inactive=30d use_temp_path=off; + server { + listen 80; + location /custom/ { + set $upstream_url $http_x_reitti_upstream_url; + proxy_pass $upstream_url; + proxy_set_header Host $proxy_host; + proxy_set_header User-Agent "Reitti/1.0"; + proxy_cache tiles; + proxy_cache_key $upstream_url; + proxy_cache_valid 200 30d; + proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; + } + } +} +NGINXEOF + systemctl reload nginx + msg_ok "Updated nginx tile cache configuration" + fi + fi + if check_for_gh_release "reitti" "dedicatedcode/reitti"; then msg_info "Stopping Service" systemctl stop reitti @@ -179,10 +247,12 @@ PROPEOF USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "reitti" "dedicatedcode/reitti" "singlefile" "latest" "/opt/reitti" "reitti-app.jar" mv /opt/reitti/reitti-*.jar /opt/reitti/reitti.jar + msg_warn "v5 runs a one-time database migration on first start (GPS points → device table). This may take several minutes on large datasets — do not interrupt the container." msg_info "Starting Service" systemctl start reitti msg_ok "Started Service" msg_ok "Updated successfully!" + msg_warn "Post-upgrade: Verify each API token has a Device assigned in Settings → API Tokens. Tokens without a device cannot ingest location data in v5." fi exit } diff --git a/install/reitti-install.sh b/install/reitti-install.sh index 2810b1495..512b0cd13 100644 --- a/install/reitti-install.sh +++ b/install/reitti-install.sh @@ -30,27 +30,30 @@ mv /opt/reitti/reitti-*.jar /opt/reitti/reitti.jar msg_info "Installing Nginx Tile Cache" mkdir -p /var/cache/nginx/tiles -cat </etc/nginx/nginx.conf +cat <<'NGINXEOF' >/etc/nginx/nginx.conf user www-data; events { worker_connections 1024; } http { + resolver 1.1.1.1 8.8.8.8 valid=30s ipv6=off; proxy_cache_path /var/cache/nginx/tiles levels=1:2 keys_zone=tiles:10m max_size=1g inactive=30d use_temp_path=off; server { listen 80; - location / { - proxy_pass https://tile.openstreetmap.org/; - proxy_set_header Host tile.openstreetmap.org; + location /custom/ { + set $upstream_url $http_x_reitti_upstream_url; + proxy_pass $upstream_url; + proxy_set_header Host $proxy_host; proxy_set_header User-Agent "Reitti/1.0"; proxy_cache tiles; + proxy_cache_key $upstream_url; proxy_cache_valid 200 30d; proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; } } } -EOF +NGINXEOF chown -R www-data:www-data /var/cache/nginx chmod -R 750 /var/cache/nginx systemctl restart nginx @@ -71,6 +74,7 @@ server.compression.mime-types=text/plain,application/json logging.level.root=INFO logging.level.org.hibernate.engine.jdbc.spi.SqlExceptionHelper=FATAL logging.level.com.dedicatedcode.reitti=INFO +logging.level.org.quartz.core.ErrorLogger=FATAL # Internationalization spring.messages.basename=messages @@ -82,7 +86,7 @@ spring.messages.fallback-to-system-locale=false spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/$PG_DB_NAME spring.datasource.username=$PG_DB_USER spring.datasource.password=$PG_DB_PASS -spring.datasource.hikari.maximum-pool-size=20 +spring.datasource.hikari.maximum-pool-size=30 # Redis configuration spring.data.redis.host=127.0.0.1 @@ -92,20 +96,23 @@ spring.data.redis.password= spring.data.redis.database=0 spring.cache.redis.key-prefix= -spring.cache.cache-names=processed-visits,significant-places,users,magic-links,configurations,transport-mode-configs,avatarThumbnails,avatarData,user-settings +spring.cache.cache-names=processed-visits,significant-places,users,magic-links,configurations,transport-mode-configs,avatarThumbnails,avatarData,user-settings,devices,mapStyles,mapStyleJson spring.cache.redis.time-to-live=1d # Upload configuration spring.servlet.multipart.max-file-size=5GB spring.servlet.multipart.max-request-size=5GB +spring.servlet.multipart.resolve-lazily=true server.tomcat.max-part-count=100 +spring.mvc.async.request-timeout=600000 -# Rqueue configuration -rqueue.web.enable=false -rqueue.job.enabled=false -rqueue.message.durability.in-terminal-state=0 -rqueue.key.prefix=\${spring.cache.redis.key-prefix} -rqueue.message.converter.provider.class=com.dedicatedcode.reitti.config.RQueueCustomMessageConverter +# Quartz Scheduler configuration +spring.quartz.job-store-type=jdbc +spring.quartz.jdbc.initialize-schema=never +spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate +spring.quartz.properties.org.quartz.jobStore.isClustered=false +spring.quartz.properties.org.quartz.jobStore.tablePrefix=qrtz_ +spring.quartz.properties.org.quartz.threadPool.threadCount=5 # Application-specific settings reitti.server.advertise-uri= @@ -117,18 +124,25 @@ reitti.security.oidc.enabled=false reitti.security.oidc.registration.enabled=false reitti.import.batch-size=10000 -reitti.import.processing-idle-start-time=10 +reitti.import.grace-time-seconds=30 +reitti.import.staging.cleanup.cron=0 0 4 * * * + +reitti.batching.max-batch-size=100 +reitti.batching.max-wait-time=5 reitti.geo-point-filter.max-speed-kmh=1000 reitti.geo-point-filter.max-accuracy-meters=100 reitti.geo-point-filter.history-lookback-hours=24 reitti.geo-point-filter.window-size=50 -reitti.process-data.schedule=0 */10 * * * * reitti.process-data.refresh-views.schedule=0 0 4 * * * reitti.imports.schedule=0 5/10 * * * * reitti.imports.owntracks-recorder.schedule=\${reitti.imports.schedule} +reitti.jobs.cleanup.cron=0 0 4 * * ? +reitti.jobs.cleanup.max-age-hours=24 +reitti.db-janitor.schedule=0 0 4 * * ? + # Geocoding service configuration reitti.geocoding.max-errors=10 reitti.geocoding.photon.base-url=