MinIO Reverse Proxy - Template from Nginx

1. The problem I’m having:

I’m trying to use reverse_proxy for my MinIO instance, which is running on a different server. On the same server as MinIO a nginx instance is working, and can successfully use reverse proxy with https.

I’m not sure if the rewrite is the issue or the header. Here’s my nginx config:

server {
   listen       443 ssl default_server;
   listen  [::]:443 ssl default_server;
   http2 on;
   http3 on;
   http3_hq on;

   include snippets/self-signed.conf;
   include snippets/ssl-params.conf;

   server_name  s3.home.local;

   # Allow special characters in headers
   ignore_invalid_headers off;
   # Allow any size file to be uploaded.
   # Set to a value such as 1000m; to restrict file size to a specific value
   client_max_body_size 0;
   # Disable buffering
   proxy_buffering off;
   proxy_request_buffering off;

   location / {
      proxy_set_header Host $http_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_connect_timeout 300;
      # Default is HTTP/1, keepalive is only enabled in HTTP/1.1
      proxy_http_version 1.1;
      proxy_set_header Connection "";
      chunked_transfer_encoding off;

      proxy_pass http://localhost:9000;
   }

   location /console/ {
      rewrite ^/console/(.*) /$1 break;
      proxy_set_header Host $http_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-NginX-Proxy true;

      # This is necessary to pass the correct IP to be hashed
      real_ip_header X-Real-IP;

      proxy_connect_timeout 300;

      # To support websockets in MinIO versions released after January 2023
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      # Some environments may encounter CORS errors (Kubernetes + Nginx Ingress)
      # Uncomment the following line to set the Origin request to an empty string
      # proxy_set_header Origin '';

      chunked_transfer_encoding off;

      proxy_pass http://localhost:9001;
   }
}

Note: nginx uses my internal domain, caddy my external.
MinIO env settings will point to s3.neus.xyz when testing Caddy.

2. Error messages and/or full log output:

3. Caddy version:

v2.6.1 h1:EDqo59TyYWhXQnfde93Mmv4FJfYe00dO60zMiEt+pzo=

4. How I installed and ran Caddy:

through apt

a. System environment:

Debian 12 Bookworm

b. Command:

nothing else than caddy reload or occasionally systemctl restart caddy

c. Service/unit/compose file:

d. My complete Caddy config:

s3.neus.xyz {
	import cloudflare
	import eth0

	encode gzip

	log {
		output file /var/log/caddy/s3.neus.xyz.log
		format console
	}
	route {
		rewrite /console/* / # unsure about this at all
		reverse_proxy valhalla.home.local:9001
    }
    reverse_proxy valhalla.home.local:9000

}

5. Links to relevant resources:

https://min.io/docs/minio/linux/integrations/setup-nginx-proxy-with-minio.html

Nevermind, I just realized how awful and faulty my configuration was

s3.neus.xyz {
	import cloudflare
	import eth0

	encode gzip

	log {
		output file /var/log/caddy/s3.neus.xyz.log
		format console
	}
	
	route /console/* {
    uri strip_prefix /console
    reverse_proxy valhalla.home.local:9001 {
    	header_up Connection {http.request.header.Connection}
      header_up Upgrade {http.request.header.Upgrade}
    }
  }

  reverse_proxy valhalla.home.local:9000

}

It seems to work with this, but yet there’s still something fishy. When I use nginx I can navigate between the menus with ease, but with caddy the console sometimes have hiccups, like when I click on “buckets” it’s just empty.

Does anybody have a better config for this?

A better way to write this would be:

handle_path /console/* {
	reverse_proxy valhalla.home.local:9001
}

handle {
	reverse_proxy valhalla.home.local:9000
}

Using handle blocks makes the proxies mutually exclusive, and handle_path has built-in prefix stripping logic. Also you shouldn’t use those header_up lines, Caddy handles headers correctly by default for WebSockets.

But keep in mind when you’re stripping a path prefix before proxying:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.