Serving minio buckets with Traefik and nginx

I'm trying to setup bucket based routing to serve sites from minio with routing being handled by Traefik and an Nginx reverse proxy. I have a sample site here https://minio.unexpectedeof.xyz/static/index.html. All the routing for that is handled by Traefik. I want to add Nginx as a reverse proxy so I can route different domains to different buckets as shown in the minio docs https://docs.min.io/docs/setup-nginx-proxy-with-minio.html. When I do this though I get a redirect loop that ends with a 302 https://blog.unexpectedeof.xyz. I get that this is happening because of the proxy upstream_addr, but I was wondering if anybody has setup similar or had ideas for how I might tweak the routing and proxy interactions. I would like to preserve the origin domain (blog, www etc) for the user and not display the minio bucket domain.

nginx.conf

events {

}

http {

  log_format  proxy '$remote_addr - $remote_user [$time_local] "$host$request_uri" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"'
                    '--- Upstream: $upstream_addr and $upstream_status';

  server {

    access_log /var/log/nginx/access.log proxy;

    server_name blog.unexpectedeof.xyz;

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

    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_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.unexpectedeof.xyz; 
    }
  }
}

docker-compose.yml

version: "3.3"

services:

  traefik:
    image: "traefik:v2.2"
    container_name: "traefik"
    restart: unless-stopped
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.ueof.acme.dnschallenge=true"
      - "--certificatesresolvers.ueof.acme.dnschallenge.provider=gandiv5"
        # Remove acme.json if testing against stage then switching over
        #      - "--certificatesresolvers.ueof.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
      - "--certificatesresolvers.ueof.acme.caserver=https://acme-v02.api.letsencrypt.org/directory"
      - "--certificatesresolvers.ueof.acme.email=alexander@unexpectedeof.net"
      - "--certificatesresolvers.ueof.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    environment:
      - "GANDIV5_API_KEY=
    volumes:
      - "./letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.rule=Host(`traefik.unexpectedeof.xyz`)"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.tls.certresolver=ueof"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.middlewares=traefik-auth"
      # middleware redirect
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      # global redirect to https
      - "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"
      - "traefik.http.routers.redirs.entrypoints=web"
      - "traefik.http.routers.redirs.middlewares=redirect-to-https"
      # Must escape $ with $
      - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:"

  whoami:
    image: "containous/whoami"
    container_name: "whoami"
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.unexpectedeof.xyz`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls.certresolver=ueof"

  giteadb:
    image: postgres:9.6
    container_name: "giteadb"
    restart: unless-stopped
    environment:
      - POSTGRES_USER=gitea
      - POSTGRES_PASSWORD=
      - POSTGRES_DB=gitea
    volumes:
      - ./postgres:/var/lib/postgresql/data

  gitea:
    image: gitea/gitea:1
    container_name: "gitea"
    restart: unless-stopped
    environment:
      - USER_UID=1001
      - USER_GID=1001
      - DOMAIN=git.unexpectedeof.xyz
      - SSH_DOMAIN=git.unexpectedeof.xyz
      - SSH_LISTEN_PORT=22
      - DB_TYPE=postgres
      - DB_HOST=giteadb:5432
      - DB_NAME=gitea
      - DB_USER=gitea
      - DB_PASSWD=
      - RUN_MODE=prod
      - DISABLE_REGISTRATION=true
      - INSTALL_LOCK=false
      - SECRET_KEY=
    volumes:
      - ./gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "22:22"
    depends_on:
      - giteadb
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.gitea-web.rule=Host(`git.unexpectedeof.xyz`)"
      - "traefik.http.routers.gitea-web.entrypoints=websecure"
      - "traefik.http.routers.gitea-web.tls.certresolver=ueof"
      - "traefik.http.routers.gitea-web.service=gitea-web-svc"
      - "traefik.http.services.gitea-web-svc.loadbalancer.server.port=3000"
      - "traefik.tcp.routers.gitea-ssh.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.gitea-ssh.entrypoints=ssh"
      - "traefik.tcp.routers.gitea-ssh.service=gitea-ssh-svc"
      - "traefik.tcp.services.gitea-ssh-svc.loadbalancer.server.port=22"

  minio:
    image: minio/minio
    container_name: "minio"
    restart: unless-stopped
    command: server /data
    volumes:
      - "./minio/data:/data"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.minio.rule=Host(`minio.unexpectedeof.xyz`)"
      - "traefik.http.routers.minio.entrypoints=websecure"
      - "traefik.http.routers.minio.tls.certresolver=ueof"
    environment:
      - MINIO_SECRET_KEY=
      - MINIO_ACCESS_KEY=

  nginx:
    image: nginx:1.19-alpine
    container_name: "nginx"
    restart: unless-stopped
    volumes:
      - "./nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
      - "./var/www/html:/var/www/html:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nginx.rule=Host(`blog.unexpectedeof.xyz`)"
      - "traefik.http.routers.nginx.entrypoints=websecure"
      - "traefik.http.routers.nginx.tls.certresolver=ueof"

I got rid of nginx and handled this with middleware for anybody else that may want to do something similar.

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.minio.rule=Host(`minio.unexpectedeof.xyz`)"
      - "traefik.http.routers.minio.entrypoints=websecure"
      - "traefik.http.routers.minio.tls.certresolver=ueof"
      - "traefik.http.middlewares.add-blog-bucket.addprefix.prefix=/static"
      - "traefik.http.middlewares.root-to-index.redirectregex.regex=^https:\\/\\/([^\\/]+)\\/?$$"
      - "traefik.http.middlewares.root-to-index.redirectregex.replacement=https://$$1/index.html"
      - "traefik.http.middlewares.pathing.chain.middlewares=root-to-index,add-blog-bucket"
      - "traefik.http.routers.blog.rule=Host(`blog.unexpectedeof.xyz`)"
      - "traefik.http.routers.blog.entrypoints=websecure"
      - "traefik.http.routers.blog.tls.certresolver=ueof"
      - "traefik.http.routers.blog.middlewares=pathing"
1 Like