Как правильно настроить Nginx для сервера MinIO, работающего как сервис Docker

Вопрос или проблема

Я просто пытаюсь реализовать прокси-передачу от Nginx к службе Docker Minio; однако с моим текущим конфигурационным файлом nginx это не работает так, как ожидалось, и продолжает загружаться, когда я просматриваю любые ведра Minio из консоли Minio (веб-интерфейс). Обратите внимание, что сервер minio работает нормально, когда его просматривают из локальной сети. Текущий конфигурационный файл nginx для службы docker minio выглядит следующим образом:

Конфигурационный файл Nginx:

server {
    listen 80;
    listen [::]:80;
    server_name s3.mysite.com;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name s3.mysite.com;

    ssl_certificate /etc/letsencrypt/live/s3.mysite.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/s3.mysite.com/privkey.pem;

    # Для разрешения специальных символов в заголовках
    ignore_invalid_headers off;
    # Разрешить загрузку файлов любого размера.
    # Установите значение, например, 1000m, чтобы ограничить размер файла до определенного значения
    client_max_body_size 0;
    # Чтобы отключить буферизацию
    proxy_buffering off;

    # Прокси-запросы к ведру "photos" на сервер MinIO, работающий на порту 9000
    location /blog/ {
        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;
        # По умолчанию это HTTP/1, keepalive включен только в HTTP/1.1
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        chunked_transfer_encoding off;

        proxy_pass http://minio:9000;
    }

    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;
        # По умолчанию это HTTP/1, keepalive включен только в HTTP/1.1
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        chunked_transfer_encoding off;

        proxy_pass http://minio:9001;
    }
}

Файл compose Docker:

  minio:
    image: minio/minio
    ports:
        - "9000:9000"
        - "9001:9001"
    volumes:
      - ../s3-bucket:/data
    env_file:
      - config/.env.minio.prod
    command: server /data --console-address :9001

Ошибка из интернет-браузера:

Firefox не может установить соединение с сервером по адресу wss://s3.mysite.com/ws/objectManager. BrowserHandler.tsx:105:14
Ошибка в соединении websocket. Пытаемся переподключиться... BrowserHandler.tsx:140:12
Websocket отключен. Пытаемся переподключиться... BrowserHandler.tsx:132:12
Websocket недоступен. BrowserHandler.tsx:126:14
Websocket недоступен.

Я думаю, что в конфигурационном файле Nginx чего-то не хватает, чтобы достичь обоих портов на службе Docker. Насколько я понимаю, порт 9001 используется для консольной функциональности, а порт 9000 для обработки данных. Но я не уверен, как правильно реализовать прокси-передачу к обоим портам.

У меня была аналогичная задача всего несколько дней назад. Вот что я сделал

  1. Создать две записи A у моего провайдера DNS minioapi.mypage.com и minioweb.mypage.com для доступа к API и веб-консоли

  2. Использовать собственный файл nginx.conf, как предложила команда Minio
    https://min.io/docs/minio/linux/integrations/setup-nginx-proxy-with-minio.html

  3. Развернуть как Minio, так и nginx в виде Docker Compose файла

Для справки, вот мой файл nginx.conf, который позже монтируется в мой контейнер nginx

  user www-data;
  worker_processes auto;
  pid /run/nginx.pid;
  events {}
  
  http {
  
  include /etc/nginx/mime.types;
  server_tokens off;
  
  server {
  listen       443 ssl;
  listen  [::]:443 ssl;
  server_name  minioapi.mypage.com;
  ignore_invalid_headers off;
  client_max_body_size 0;
  proxy_buffering off;
  proxy_request_buffering off;
  ssl_certificate           /etc/nginx/ssl/archive/npm-4/fullchain1.pem;
  ssl_certificate_key       /etc/nginx/ssl/archive/npm-4/privkey1.pem;
  ssl_session_cache   shared:SSL:10m;
  ssl_session_timeout 1440m;
  ssl_session_tickets off;
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers off;
  ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA";
  
  access_log /dev/stdout;
  error_log /dev/stdout info;
  
  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;
  proxy_http_version 1.1;
  proxy_set_header Connection "";
  chunked_transfer_encoding off;
  proxy_pass http://192.168.1.161:9000/;
  }
  }
  
  server {
  listen       443 ssl;
  listen  [::]:443 ssl;
  server_name minioweb.mypage.com;
  ignore_invalid_headers off;
  client_max_body_size 0;
  proxy_buffering off;
  proxy_request_buffering off;
  ssl_certificate           /etc/nginx/ssl/archive/npm-3/fullchain1.pem;
  ssl_certificate_key       /etc/nginx/ssl/archive/npm-3/privkey1.pem;
  ssl_session_cache   shared:SSL:10m;
  ssl_session_timeout 1440m;
  ssl_session_tickets off;
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers off;
  ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA";
  access_log /dev/stdout;
  error_log /dev/stdout info;
  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_set_header X-NginX-Proxy true;
  real_ip_header X-Real-IP;
  proxy_connect_timeout 300;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  chunked_transfer_encoding off;
  proxy_pass http://192.168.1.161:9090/; 
  }
  }
  
  server {
  listen 80 http2 default_server;
  return 301 https://$host$request_uri;
  }
  
  
  }

Вот мой docker compose :

---
version: '3.7'
services:
  minio:
    image: quay.io/minio/minio:RELEASE.2023-06-19T19-52-50Z
    container_name : minio
    ports:
      - 9000:9000
      - 9090:9090
      - 8021:8021
    environment:
      MINIO_ROOT_USER: rootuser
      MINIO_ROOT_PASSWORD: rootpassword
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3
    volumes:
      - ${HOME}/minio/data:/data
    command: server /data --console-address ":9090"

  nginx-rp:
    container_name: nginx-reverse-proxy
    image: nginx:1.25.1
    volumes:
        - ./conf:/etc/nginx:ro    
    ports:
    - "80:80"
    - "443:443"    
    restart: unless-stopped

Вы не настроили свой прокси nginx для реализации вебсокетов.

Вам нужно что-то вроде….

location /ws/ {
            proxy_pass http://minio:9001;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Host $host;
        }

Ответ или решение

Настройка Nginx для MinIO, работающего в качестве Docker-сервиса

Ваша текущая конфигурация Nginx для проксирования запросов к серверу MinIO требует доработки, особенно в части обработки веб-сокетов. Здесь я представлю детальное решение вашей проблемы, чтобы обеспечить корректную работу управления объектами через веб-интерфейс MinIO.

Общая структура Nginx

Для корректной работы Nginx в роли обратного прокси-сервера для MinIO, который работает на разных портов (9000 для API и 9001 для веб-консоли), необходимо настроить два отдельных блока location. Один из них должен обрабатывать веб-сокеты, что решит проблему с соединением, упомянутую в вашем запросе.

Вот рекомендованная конфигурация Nginx:

server {
    listen 80;
    listen [::]:80;
    server_name s3.mysite.com;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name s3.mysite.com;

    ssl_certificate /etc/letsencrypt/live/s3.mysite.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/s3.mysite.com/privkey.pem;

    client_max_body_size 0;  # Отключаем ограничение по размеру
    proxy_buffering off;      # Отключаем буферизацию

    # Обработка API MinIO на порту 9000
    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;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        chunked_transfer_encoding off;

        proxy_pass http://minio:9000;
    }

    # Обработка веб-консоли 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 $http_host;

        proxy_connect_timeout 300;
    }
}

Объяснение изменений

  1. Обработка веб-сокетов: Добавлен блок location /ws/, который отвечает за проксирование соединений websocket. Без этого блока браузер не сможет корректно соединиться с сервисами, требующими поддержку веб-сокетов.

  2. Использование правильных портов:

    • proxy_pass http://minio:9000; — здесь обрабатываются основные API-запросы MinIO.
    • В блоке location /ws/ настроено проксирование на порт 9001, что позволяет корректно взаимодействовать с веб-интерфейсом MinIO.

Docker Compose

Убедитесь, что ваш docker-compose.yml выглядит следующим образом:

version: '3.7'
services:
  minio:
    image: minio/minio
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - ../s3-bucket:/data
    env_file:
      - config/.env.minio.prod
    command: server /data --console-address :9001

  nginx:
    image: nginx:1.25.1
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - minio
    restart: unless-stopped

Заключение

Следуя представленным рекомендациям, вы должны получить работающий прокси-сервер Nginx, корректно проксирующий как API MinIO, так и веб-консоль. Проверьте, чтобы DNS-записи были настроены правильно и указывали на ваш сервер с установленным Nginx. После внесения изменений не забудьте перезагрузить Nginx:

docker-compose exec nginx nginx -s reload

Эта настройка обеспечит стабильную работу вашего MinIO, а пользователи смогут успешно подключаться к вашему веб-интерфейсу без проблем с веб-сокетами.

Оцените материал
Добавить комментарий

Капча загружается...