Вопрос или проблема
Я просто пытаюсь реализовать прокси-передачу от 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
для обработки данных. Но я не уверен, как правильно реализовать прокси-передачу к обоим портам.
У меня была аналогичная задача всего несколько дней назад. Вот что я сделал
-
Создать две записи A у моего провайдера DNS minioapi.mypage.com и minioweb.mypage.com для доступа к API и веб-консоли
-
Использовать собственный файл nginx.conf, как предложила команда Minio
https://min.io/docs/minio/linux/integrations/setup-nginx-proxy-with-minio.html -
Развернуть как 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;
}
}
Объяснение изменений
-
Обработка веб-сокетов: Добавлен блок
location /ws/
, который отвечает за проксирование соединений websocket. Без этого блока браузер не сможет корректно соединиться с сервисами, требующими поддержку веб-сокетов. -
Использование правильных портов:
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, а пользователи смогут успешно подключаться к вашему веб-интерфейсу без проблем с веб-сокетами.