14

I am trying to redirect a example.com/minio location to minio console, which is run behind a nginx proxy both run by a docker compose file. My problem is that, when I'm trying to reverse proxy the minio endpoint to a path, like /minio it does not work, but when I run the minio reverse proxy on root path in the nginx reverse proxy, it works. I seriously cannot findout what the problem might be.

This is my compose file:

services:
  nginx:
    container_name: nginx
    image: nginx
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - ./log/nginx:/var/log/nginx/
  minio:
    image: minio/minio
    container_name: minio
    volumes:
      - ./data/minio/:/data
    command: server /data --address ':9000' --console-address ':9001'
    environment:
      MINIO_ROOT_USER: minio_admin
      MINIO_ROOT_PASSWORD: minio_123456
    ports:
      - 9000
      - 9001
    restart: always
    logging:
      driver: "json-file"
      options:
        max-file: "10"
        max-size: 20m
    healthcheck:
      test: ["CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

My nginx configuration is like this:

server {
    listen 80;
    server_name example.com;

    # To 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;
    # To disable buffering
    proxy_buffering off;


    access_log /var/log/nginx/service-access.log;
    error_log /var/log/nginx/service-error.log debug;

    location / {
        return 200 "salam";
        default_type text/plain;
    }
    location /minio {
        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 Host $http_host;

        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://minio:9001;
    }
}

The picture I'm seeing of minio console at the domain is this: enter image description here

And the response of curling the endpoint ($ curl -k http://example.com/minio):

<null>
    <html lang="en">
        <head>
            <meta charset="utf-8" />
            <base href="/" />
            <meta content="width=device-width,initial-scale=1" name="viewport" />
            <meta content="#081C42" media="(prefers-color-scheme: light)" name="theme-color" />
            <meta content="#081C42" media="(prefers-color-scheme: dark)" name="theme-color" />
            <meta content="MinIO Console" name="description" />
            <link href="./styles/root-styles.css" rel="stylesheet" />
            <link href="./apple-icon-180x180.png" rel="apple-touch-icon" sizes="180x180" />
            <link href="./favicon-32x32.png" rel="icon" sizes="32x32" type="image/png" />
            <link href="./favicon-96x96.png" rel="icon" sizes="96x96" type="image/png" />
            <link href="./favicon-16x16.png" rel="icon" sizes="16x16" type="image/png" />
            <link href="./manifest.json" rel="manifest" />
            <link color="#3a4e54" href="./safari-pinned-tab.svg" rel="mask-icon" />
            <title>MinIO Console</title>
            <script defer="defer" src="./static/js/main.eec275cb.js"></script>
            <link href="./static/css/main.90d417ae.css" rel="stylesheet">
        </head>
        <body>
            <noscript>You need to enable JavaScript to run this app.</noscript>
            <div id="root">
                <div id="preload">
                    <img src="./images/background.svg" />
                    <img src="./images/background-wave-orig2.svg" />
                </div>
                <div id="loader-block">
                    <img src="./Loader.svg" />
                </div>
            </div>
        </body>
    </html>
    %

6 Answers 6

11

I also struggled with this for a long time and was finally able to resolve it.

As far as I can tell, the key changes to make this work for me where:

  • Manually specifying a rewrite directive (instead of relying on the Nginx proxy_pass+URI behaviour which didn't seem to work for me).
  • Setting the resolver directive with short timeouts (so that rescheduling of services onto other nodes gets resolved).
  • Setting $upstream to prevent DNS caching.

I had to change your setup a little bit so that now the Minio S3 API is served behind minio.example.com while the UI Web Console is accessible at minio.example.com/console/.

I have edited your config files below:

docker-compose.yml:

services:
  nginx:
    container_name: nginx
    image: nginx
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - ./log/nginx:/var/log/nginx/
  minio:
    image: minio/minio
    container_name: minio
    volumes:
      - ./data/minio/:/data
    command: server /data --address ':9000' --console-address ':9001'
    environment:
      MINIO_SERVER_URL: "http://minio.example.com/"
      MINIO_BROWSER_REDIRECT_URL: "http://minio.example.com/console/"    
      MINIO_ROOT_USER: minio_admin
      MINIO_ROOT_PASSWORD: minio_123456
    ports:
      - 9000
      - 9001
    restart: always
    logging:
      driver: "json-file"
      options:
        max-file: "10"
        max-size: 20m
    healthcheck:
      test: ["CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

nginx.conf:

server {
    listen 80;
    server_name minio.example.com;

    # To 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;
    # To disable buffering
    proxy_buffering off;


    access_log /var/log/nginx/service-access.log;
    error_log /var/log/nginx/service-error.log debug;


    # Use Docker DNS
    # You might not need this section but in case you need to resolve
    # docker service names inside the container then this can be useful.
    resolver 127.0.0.11 valid=10s;
    resolver_timeout 5s;

    # Apparently the following line might prevent caching of DNS lookups
    # and force nginx to resolve the name on each request via the internal
    # Docker DNS.
    set $upstream "minio";

    # Minio Console (UI)
    location /console/ {

        # This was really the key for me. Even though the Nginx docs say 
        # that with a URI part in the `proxy_pass` directive, the `/console/`
        # URI should automatically be rewritten, this wasn't working for me.
        rewrite ^/console/(.*)$ /$1 break;

        proxy_pass http://$upstream:9001;

        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 Host $http_host;

        proxy_connect_timeout 300;

        # To support websocket
        # Default is HTTP/1, keepalive is only enabled in HTTP/1.1
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        chunked_transfer_encoding off;    
    }


    # Proxy requests to the Minio API on port 9000
    location / {

        proxy_pass http://$upstream:9000;

        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 Host $http_host;

        proxy_connect_timeout 300;

        # To support websocket
        # Default is HTTP/1, keepalive is only enabled in HTTP/1.1
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        chunked_transfer_encoding off;
    }

}

HTH!

Sign up to request clarification or add additional context in comments.

2 Comments

Note this will only work with the trailing slash of location /console/ directive. It cost me few hours...
rewrite resolved my issue, thanks!
5

minio doesn't work under non default path like location /minio

You need to use location / { .... proxy_pass http://localhost:9001; } or add another server block to nginx with subdomain like this

server{

listen 80;

server_name minio.example.com;;

     location / {
       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 Host $http_host;

       proxy_pass http://localhost:9001;
   }
}

4 Comments

I need it to work under a subpath really, but since it's not possible I have to accept your answer. Hopefully someday it will work out!
Sadly I came to the same conclusion after 4 months... The furthest I got is Uncaught SyntaxError: Unexpected token '<' (at main.069a61a0.js:1:1) in browser console when you set MINIO_BROWSER_REDIRECT_URL to match reverse proxy path. Atop of reverse proxy I also need SSL.
I've hit a similar issue where the wss://host:9001/ws/objectManager is giving me a 403. While I've yet to find the real answer to this issue, this specific SO answer goes against the Minio Docs: min.io/docs/minio/linux/integrations/…
minio does work under non default path like location /minio. Just need to add the browser redirect url setting to minio server ref: stackoverflow.com/a/76760911/2018712
5

Ensure you have configured minio server with the browser redirect url to reflect your sub path.

This can be set as environment variable like

MINIO_SERVER_URL="https://yourdomain.com"
MINIO_BROWSER_REDIRECT_URL="https://yourdomain.com/your_subpath"

Ref :https://min.io/docs/minio/linux/integrations/setup-nginx-proxy-with-minio.html enter image description here

2 Comments

This should be the accepted answer. You can't proxy the API under a /path but you certainly can proxy the UI under a path
Setting MINIO_SERVER_URL is not necessary for collocated minio server and console, or even leading to connection issues due to use untrusted self-signed certificate for serving HTTPS. The official document is misleading about setting this variable, as they might ignore the situation that self-signed certificate might be used. Please see the explanation from another thread for this issue.
2

i facing same trouble today.

Proxy for buckets is easy:

location /s3 {
            proxy_http_version 1.1;
            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_buffering off;
            tcp_nodelay on;


        proxy_pass http://minio-api:9000; # This uses the upstream directive definition to load balance
}

but to access Web Console we need to use some trick with rewriting base href of application. Fortunately, Base href located in <head> tag and we can easily rewrite it:

 location /minio/ui/ {
            rewrite ^/minio/ui/(.*)$ /$1 break;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
            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 websocket
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";

            chunked_transfer_encoding off;
            proxy_pass http://minio-web:9001; # This uses the upstream directive definition to load balance

            # This one rewrite with sub_filter plugin
            sub_filter '<base href="/"/>' '<base href="/minio/ui/"/>';

   }

Btw, if we are not rewrite base href, we will got blank page, a lot of 404 errors in web-console and message like

"You need to enable JavaScript to run this app."

Hope, this is solve a lot of time for someone else!

Comments

0

when Minio UI loads, it uses root path to load static and js files you need to add these to your nginx configs:

    # Handle static assets for MinIO UI
    location ~ ^/(static|icons|images|fonts)/ {
        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;
        proxy_http_version 1.1;

        proxy_pass http://minio:9001;
    }

    # Additional location to handle other potential asset paths
    location ~ ^/.*\.(js|css|png|jpg|jpeg|gif|ico)$ {
        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;
        proxy_http_version 1.1;

        proxy_pass http://minio:9001;
    }

therefore if you want to fix websocket issue and API calls error you need to add these configs :

   location /api/ {
        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;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_pass http://minio:9001;
    }

    location /ws/ {
        proxy_pass http://minio:9001;
        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_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
    }

Comments

-3

https://github.com/arschles/minio-howto/blob/master/setup-Nginx-proxy-with-Minio-Server.md

if you use a nginx docker container, add this file to /etc/nginx/conf.d and remove the existing default.conf file in same directory.

3 Comments

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
This doesn't even answer the question, it does not install to a specific path.
The linked resource provides almost no useful information on solving the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.