From 8e86e0b8e75ab8a4b5becac21028d0edfab23d3b Mon Sep 17 00:00:00 2001 From: Alexandre <44178713+alexbelgium@users.noreply.github.com> Date: Thu, 29 Jan 2026 17:38:17 +0100 Subject: [PATCH 1/2] Update BirdNET-PiPy nginx configs --- birdnet-pipy/CHANGELOG.md | 2 ++ birdnet-pipy/Dockerfile | 1 + birdnet-pipy/config.yaml | 2 +- .../etc/cont-init.d/32-nginx_ingress.sh | 19 +++++++++++++------ .../rootfs/etc/nginx/servers/nginx.conf | 8 ++++---- 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/birdnet-pipy/CHANGELOG.md b/birdnet-pipy/CHANGELOG.md index 8c8616f5c..82700cb46 100644 --- a/birdnet-pipy/CHANGELOG.md +++ b/birdnet-pipy/CHANGELOG.md @@ -1,3 +1,5 @@ +## 0.6.2 (29-01-2026) +- Use upstream nginx.conf and generate ingress config at startup ## 0.6.1 (29-01-2026) - Minor bugs fixed ## 0.2 (29-01-2026) diff --git a/birdnet-pipy/Dockerfile b/birdnet-pipy/Dockerfile index 3f15db650..5fb6411c3 100644 --- a/birdnet-pipy/Dockerfile +++ b/birdnet-pipy/Dockerfile @@ -57,6 +57,7 @@ RUN chmod 744 /ha_lsio.sh && if grep -qr "lsio" /etc; then /ha_lsio.sh "$CONFIGL # Copy local files COPY rootfs/ / RUN find /etc -type f \( -name "*.sh" -o -path "*/services.d/*/run" \) -exec chmod +x {} \; +COPY --from=frontend-builder /src/frontend/nginx.conf /etc/nginx/servers/nginx.conf # Uses /bin for compatibility purposes # hadolint ignore=DL4005 diff --git a/birdnet-pipy/config.yaml b/birdnet-pipy/config.yaml index 18502250c..b565e6680 100644 --- a/birdnet-pipy/config.yaml +++ b/birdnet-pipy/config.yaml @@ -98,4 +98,4 @@ schema: ssl: bool? slug: birdnet-pipy url: https://github.com/alexbelgium/hassio-addons/tree/master/birdnet-pipy -version: "0.6.1" +version: "0.6.2" diff --git a/birdnet-pipy/rootfs/etc/cont-init.d/32-nginx_ingress.sh b/birdnet-pipy/rootfs/etc/cont-init.d/32-nginx_ingress.sh index 556f81b0b..e38227801 100755 --- a/birdnet-pipy/rootfs/etc/cont-init.d/32-nginx_ingress.sh +++ b/birdnet-pipy/rootfs/etc/cont-init.d/32-nginx_ingress.sh @@ -14,12 +14,19 @@ ingress_interface="$(bashio::addon.ip_address)" ingress_entry="$(bashio::addon.ingress_entry)" ingress_entry_modified="$(echo "$ingress_entry" | sed 's/[@_!#$%^&*()<>?/\|}{~:]//g')" -sed -i "s/%%port%%/${ingress_port}/g" /etc/nginx/servers/ingress.conf -sed -i "s/%%interface%%/${ingress_interface}/g" /etc/nginx/servers/ingress.conf -sed -i "s#%%ingress_entry%%#${ingress_entry}#g" /etc/nginx/servers/ingress.conf -sed -i "s#%%ingress_entry_modified%%#/${ingress_entry_modified}#g" /etc/nginx/servers/ingress.conf -sed -i "s#%%ingress_entry%%#${ingress_entry}#g" /etc/nginx/servers/nginx.conf -sed -i "s#%%ingress_entry_modified%%#/${ingress_entry_modified}#g" /etc/nginx/servers/nginx.conf +sed -i \ + -e "s|proxy_pass http://api|proxy_pass http://127.0.0.1|g" \ + -e "s|proxy_pass http://icecast|proxy_pass http://127.0.0.1|g" \ + /etc/nginx/servers/nginx.conf + +cp /etc/nginx/servers/nginx.conf /etc/nginx/servers/ingress.conf +sed -i \ + -e "s|listen 80;|listen ${ingress_interface}:${ingress_port} default_server;|g" \ + -e "/index index.html;/a\\ include /etc/nginx/includes/ingress_params.conf;" \ + /etc/nginx/servers/ingress.conf + +sed -i "s#%%ingress_entry%%#${ingress_entry}#g" /etc/nginx/includes/ingress_params.conf +sed -i "s#%%ingress_entry_modified%%#/${ingress_entry_modified}#g" /etc/nginx/includes/ingress_params.conf # Set DNS resolver for internal requests sed -i "s/%%dns_host%%/127.0.0.11/g" /etc/nginx/includes/resolver.conf diff --git a/birdnet-pipy/rootfs/etc/nginx/servers/nginx.conf b/birdnet-pipy/rootfs/etc/nginx/servers/nginx.conf index 019995942..7feeb65ac 100644 --- a/birdnet-pipy/rootfs/etc/nginx/servers/nginx.conf +++ b/birdnet-pipy/rootfs/etc/nginx/servers/nginx.conf @@ -21,7 +21,7 @@ server { # API proxy - forward /api/ requests to API server # IMPORTANT: ^~ modifier prevents regex matches (like .png) from taking precedence location ^~ /api/ { - proxy_pass http://127.0.0.1:5002; + proxy_pass http://api:5002; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -37,7 +37,7 @@ server { # Internal auth verification endpoint (for nginx auth_request) location = /internal/auth { internal; - proxy_pass http://127.0.0.1:5002/api/auth/verify; + proxy_pass http://api:5002/api/auth/verify; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header X-Original-URI $request_uri; @@ -56,7 +56,7 @@ server { auth_request /internal/auth; error_page 401 = @stream_unauthorized; - proxy_pass http://127.0.0.1:8888/; + proxy_pass http://icecast:8888/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -83,7 +83,7 @@ server { # Socket.IO WebSocket proxy - forward /socket.io/ requests to API server location /socket.io/ { - proxy_pass http://127.0.0.1:5002/socket.io/; + proxy_pass http://api:5002/socket.io/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; From e75cf4beea7d50e6d4281c6165effb48c8c93d03 Mon Sep 17 00:00:00 2001 From: Alexandre <44178713+alexbelgium@users.noreply.github.com> Date: Thu, 29 Jan 2026 17:40:59 +0100 Subject: [PATCH 2/2] update --- .../rootfs/etc/nginx/servers/ingress.conf | 74 -------------- .../rootfs/etc/nginx/servers/nginx.conf | 99 ------------------- 2 files changed, 173 deletions(-) delete mode 100644 birdnet-pipy/rootfs/etc/nginx/servers/ingress.conf delete mode 100644 birdnet-pipy/rootfs/etc/nginx/servers/nginx.conf diff --git a/birdnet-pipy/rootfs/etc/nginx/servers/ingress.conf b/birdnet-pipy/rootfs/etc/nginx/servers/ingress.conf deleted file mode 100644 index 391d50f7f..000000000 --- a/birdnet-pipy/rootfs/etc/nginx/servers/ingress.conf +++ /dev/null @@ -1,74 +0,0 @@ -server { - listen %%interface%%:%%port%% default_server; - - root /usr/share/nginx/html; - index index.html; - - include /etc/nginx/includes/server_params.conf; - include /etc/nginx/includes/proxy_params.conf; - - client_max_body_size 0; - - gzip on; - gzip_vary on; - gzip_min_length 1024; - gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json; - - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-Content-Type-Options "nosniff" always; - - sub_filter_once off; - sub_filter_types text/html; - sub_filter '' ''; - sub_filter 'href="/' 'href="%%ingress_entry%%/'; - sub_filter 'src="/' 'src="%%ingress_entry%%/'; - - location ^~ /api/ { - proxy_pass http://127.0.0.1:5002; - } - - location = /internal/auth { - internal; - proxy_pass http://127.0.0.1:5002/api/auth/verify; - proxy_pass_request_body off; - proxy_set_header Content-Length ""; - proxy_set_header X-Original-URI $request_uri; - proxy_set_header Cookie $http_cookie; - } - - location @stream_unauthorized { - default_type application/json; - return 401 '{"error": "Authentication required"}'; - } - - location ^~ /stream/ { - auth_request /internal/auth; - error_page 401 = @stream_unauthorized; - - proxy_pass http://127.0.0.1:8888/; - proxy_buffering off; - proxy_read_timeout 3600s; - proxy_send_timeout 3600s; - } - - location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { - expires 1y; - add_header Cache-Control "public, immutable"; - try_files $uri =404; - } - - location /socket.io/ { - proxy_pass http://127.0.0.1:5002/socket.io/; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_cache_bypass $http_upgrade; - } - - location / { - try_files $uri $uri/ /index.html; - } - - error_page 404 /index.html; - error_page 500 502 503 504 /index.html; -} diff --git a/birdnet-pipy/rootfs/etc/nginx/servers/nginx.conf b/birdnet-pipy/rootfs/etc/nginx/servers/nginx.conf deleted file mode 100644 index 7feeb65ac..000000000 --- a/birdnet-pipy/rootfs/etc/nginx/servers/nginx.conf +++ /dev/null @@ -1,99 +0,0 @@ -server { - listen 80; - server_name localhost; - root /usr/share/nginx/html; - index index.html; - - # Gzip compression - gzip on; - gzip_vary on; - gzip_min_length 1024; - gzip_proxied expired no-cache no-store private auth; - gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json; - - # Security headers - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-Content-Type-Options "nosniff" always; - - # Allow large file uploads (for database migration) - client_max_body_size 500M; - - # API proxy - forward /api/ requests to API server - # IMPORTANT: ^~ modifier prevents regex matches (like .png) from taking precedence - location ^~ /api/ { - proxy_pass http://api:5002; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-Host $host; - proxy_set_header X-Forwarded-Port $server_port; - - # Longer timeouts for migration imports - proxy_read_timeout 300s; - proxy_send_timeout 300s; - } - - # Internal auth verification endpoint (for nginx auth_request) - location = /internal/auth { - internal; - proxy_pass http://api:5002/api/auth/verify; - proxy_pass_request_body off; - proxy_set_header Content-Length ""; - proxy_set_header X-Original-URI $request_uri; - proxy_set_header Cookie $http_cookie; - } - - # Auth error handler - returns JSON for API clients - location @stream_unauthorized { - default_type application/json; - return 401 '{"error": "Authentication required"}'; - } - - # Icecast audio stream proxy - forward /stream/ requests to Icecast server - # Protected by authentication when enabled - location ^~ /stream/ { - auth_request /internal/auth; - error_page 401 = @stream_unauthorized; - - proxy_pass http://icecast:8888/; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - - # Streaming-specific settings - proxy_buffering off; - proxy_read_timeout 3600s; - proxy_send_timeout 3600s; - } - - # Handle static assets with long cache times - # Note: /api/ routes are handled above, so this only affects local static files - location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { - expires 1y; - add_header Cache-Control "public, immutable"; - try_files $uri =404; - } - - # Handle Vue.js SPA routing - serve index.html for all routes that don't match static files - location / { - try_files $uri $uri/ /index.html; - } - - # Socket.IO WebSocket proxy - forward /socket.io/ requests to API server - location /socket.io/ { - proxy_pass http://api:5002/socket.io/; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_cache_bypass $http_upgrade; - } - - # Error pages - error_page 404 /index.html; - error_page 500 502 503 504 /index.html; -}