Fix 405 on thumbnail uploads: move MinIO proxy above static asset regex

Nginx regex locations are evaluated in order — the static asset caching
rule (.jpg, .png, etc.) was matching image upload URLs before the MinIO
bucket proxy could handle them, causing PUT requests to return 405.

Moved the /indeedhub-*/ proxy location to the top of the regex block.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Dorian
2026-02-13 20:36:03 +00:00
parent fc20c625fa
commit 3e4279e252
2 changed files with 24 additions and 24 deletions

View File

@@ -20,7 +20,7 @@ services:
context: .
dockerfile: Dockerfile
args:
CACHEBUST: "9"
CACHEBUST: "10"
VITE_USE_MOCK_DATA: "false"
VITE_CONTENT_ORIGIN: ${FRONTEND_URL}
VITE_INDEEHUB_API_URL: /api

View File

@@ -16,6 +16,29 @@ server {
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# ── MinIO direct proxy (for presigned URL uploads/downloads) ──
# MUST appear before the static-asset regex locations below,
# otherwise image uploads (.jpg, .png, etc.) match the asset
# caching rule first and return 405 on PUT.
location ~ ^/(indeedhub-private|indeedhub-public)/ {
resolver 127.0.0.11 valid=30s ipv6=off;
set $minio_upstream http://minio:9000;
proxy_pass $minio_upstream;
proxy_http_version 1.1;
# Pass the original Host so MinIO's signature verification matches
# the host the presigned URL was generated for.
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Allow large file uploads (up to 5GB per chunk)
client_max_body_size 5g;
# No caching for upload responses
add_header Cache-Control "no-store";
}
# PWA Support - proper MIME types
location ~* \.(?:manifest|webmanifest|json)$ {
add_header Cache-Control "public, max-age=3600";
@@ -84,29 +107,6 @@ server {
add_header Cache-Control "no-store";
}
# ── MinIO direct proxy (for presigned URL uploads/downloads) ──
# The backend generates presigned URLs pointing to the public domain.
# This location proxies those requests to MinIO WITHOUT rewriting the
# path, so the S3v4 signature (which includes the path) stays valid.
location ~ ^/(indeedhub-private|indeedhub-public)/ {
resolver 127.0.0.11 valid=30s ipv6=off;
set $minio_upstream http://minio:9000;
proxy_pass $minio_upstream;
proxy_http_version 1.1;
# Pass the original Host so MinIO's signature verification matches
# the host the presigned URL was generated for.
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Allow large file uploads (up to 5GB per chunk)
client_max_body_size 5g;
# No caching for upload responses
add_header Cache-Control "no-store";
}
# ── WebSocket proxy to Nostr relay (Docker service) ────────
location /relay {
resolver 127.0.0.11 valid=30s ipv6=off;