diff --git a/.env.example b/.env.example index 559795b..b940f48 100644 --- a/.env.example +++ b/.env.example @@ -16,7 +16,14 @@ SAREX_MINIO_ROOT_USER=minioadmin SAREX_MINIO_ROOT_PASSWORD=minioadmin SAREX_MINIO_BUCKET=sarex-media-storage SAREX_MINIO_REGION=us-east-1 +# Внешний URL консоли MinIO (minio-домен, путь /console на верхнем nginx) +SAREX_MINIO_CONSOLE_URL=http://minio.sarex.local:9080/console + +# --- Домены верхнего nginx (замени на реальные, заведи в DNS/hosts) --- +PLATFORM_DOMAIN=sarex.local # основной домен платформы (frontend + /api) +ADMIN_DOMAIN=admin.sarex.local # RabbitMQ management UI +MINIO_DOMAIN=minio.sarex.local # MinIO: S3 API (/) + консоль (/console/) # Образы приложения (приватный реестр cr.yandex — нужен docker login) SAREX_BACKEND_IMAGE=cr.yandex/crp3ccidau046kdj8g9q/sarex-backend-dev:latest -SAREX_FRONTEND_IMAGE=cr.yandex/crp3ccidau046kdj8g9q/sarex-frontend-dev:latest +SAREX_FRONTEND_IMAGE=cr.yandex/crp3ccidau046kdj8g9q/sarex-frontend-dev:latest \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 697b67a..e7c2cbf 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -152,6 +152,8 @@ services: environment: MINIO_ROOT_USER: ${SAREX_MINIO_ROOT_USER:-minioadmin} MINIO_ROOT_PASSWORD: ${SAREX_MINIO_ROOT_PASSWORD:-minioadmin} + # Консоль отдаётся через верхний nginx на minio-домене по пути /console + MINIO_BROWSER_REDIRECT_URL: ${SAREX_MINIO_CONSOLE_URL:-http://minio.sarex.local:9080/console} ports: - "9000:9000" # S3 API - "9001:9001" # web console @@ -250,19 +252,25 @@ services: depends_on: - backend - # Верхний reverse-proxy: единая точка входа → backend / frontend / minio + # Верхний reverse-proxy: 3 домена → платформа / rabbitmq (admin) / minio nginx: image: nginx:1.27-alpine container_name: sarex-nginx restart: unless-stopped ports: - "9080:80" # 80/443 заняты k3s + environment: + # подставляются envsubst'ом в шаблон при старте контейнера + PLATFORM_DOMAIN: ${PLATFORM_DOMAIN:-sarex.local} + ADMIN_DOMAIN: ${ADMIN_DOMAIN:-admin.sarex.local} + MINIO_DOMAIN: ${MINIO_DOMAIN:-minio.sarex.local} volumes: - - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro,z # :z — SELinux label для RedOS + - ./nginx/templates:/etc/nginx/templates:ro,z # :z — SELinux label для RedOS depends_on: - backend - frontend - minio + - rabbitmq healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost/healthz"] interval: 10s diff --git a/nginx/nginx.conf b/nginx/nginx.conf deleted file mode 100644 index 3e95cdb..0000000 --- a/nginx/nginx.conf +++ /dev/null @@ -1,81 +0,0 @@ -worker_processes auto; -pid /var/run/nginx.pid; - -events { - worker_connections 1024; - use epoll; -} - -http { - include /etc/nginx/mime.types; - default_type application/octet-stream; - - sendfile on; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 300; - large_client_header_buffers 8 128k; - client_max_body_size 5000M; # крупные загрузки (снимки, облака точек) - - gzip on; - gzip_vary on; - gzip_proxied any; - gzip_comp_level 6; - gzip_types text/plain text/css application/json application/javascript text/xml application/xml; - - access_log /var/log/nginx/access.log; - error_log /var/log/nginx/error.log; - - # корректная поддержка websocket/keep-alive для upstream'ов - map $http_upgrade $connection_upgrade { - default upgrade; - '' close; - } - - upstream backend { server backend:8000; } - upstream frontend { server frontend:80; } - upstream minio_s3 { server minio:9000; } - - 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; - - server { - listen 80; - listen [::]:80; - - # healthcheck самого nginx - location = /healthz { - access_log off; - add_header Content-Type text/plain; - return 200 "ok\n"; - } - - # --- Django backend: REST API + админка --- - location /api/ { - proxy_pass http://backend; - } - location /admin/ { - proxy_pass http://backend; - } - - # --- MinIO: объекты бакета --- - # Путь НЕ переписываем — иначе ломается подпись SigV4. Чтобы медиа - # открывались из браузера, задай backend'у S3_HOST = http://<хост>:9080 - # (сейчас в compose там http://minio:9000, внутренний адрес). - location /sarex-media-storage/ { - proxy_http_version 1.1; - proxy_set_header Connection ""; - proxy_pass http://minio_s3; - } - - # --- Frontend SPA (host-приложение само отдаёт статику и роутинг) --- - location / { - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection $connection_upgrade; - proxy_pass http://frontend; - } - } -} diff --git a/nginx/templates/default.conf.template b/nginx/templates/default.conf.template new file mode 100644 index 0000000..b18f9d4 --- /dev/null +++ b/nginx/templates/default.conf.template @@ -0,0 +1,131 @@ +# Рендерится образом nginx: envsubst подставляет ${PLATFORM_DOMAIN} и т.п. +# из окружения и кладёт результат в /etc/nginx/conf.d/default.conf (внутри http{}). +# Переменные вида $host / $http_upgrade — НЕ окруженческие, envsubst их не трогает. + +large_client_header_buffers 8 128k; +client_max_body_size 5000M; # крупные загрузки (снимки, облака точек) +keepalive_timeout 300; +tcp_nopush on; + +gzip on; +gzip_vary on; +gzip_proxied any; +gzip_comp_level 6; +gzip_types text/plain text/css application/json application/javascript text/xml application/xml; + +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +upstream backend { server backend:8000; } +upstream frontend { server frontend:80; } +upstream minio_s3 { server minio:9000; } +upstream minio_console { server minio:9001; } +upstream rabbitmq_mgmt { server rabbitmq:15672; } + +# Общие проксирующие заголовки. ВАЖНО: если в location задан свой proxy_set_header, +# эти НЕ наследуются — там заголовки продублированы явно. +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; + +# ============================ Платформа (основной домен) ==================== +server { + listen 80 default_server; + server_name ${PLATFORM_DOMAIN}; + + location = /healthz { + access_log off; + add_header Content-Type text/plain; + return 200 "ok\n"; + } + + # Django backend: REST API + админка + location /api/ { proxy_pass http://backend; } + location /admin/ { proxy_pass http://backend; } + + # S3-объекты (media) по относительному пути, с поддержкой Range + location /sarex-media-storage/ { + 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_http_version 1.1; + proxy_set_header Connection ""; + proxy_set_header Range $http_range; + proxy_set_header If-Range $http_if_range; + proxy_buffering off; + proxy_request_buffering off; + proxy_max_temp_file_size 0; + proxy_pass http://minio_s3; + } + + # Frontend SPA (host-приложение само отдаёт статику и роутинг) + location / { + 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_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_pass http://frontend; + } +} + +# ======================= Admin: RabbitMQ management UI ====================== +server { + listen 80; + server_name ${ADMIN_DOMAIN}; + + location / { + 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_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_pass http://rabbitmq_mgmt; + } +} + +# ============================== MinIO (отдельный домен) ===================== +server { + listen 80; + server_name ${MINIO_DOMAIN}; + + # Веб-консоль администрирования (порт 9001). Требует у сервиса minio + # MINIO_BROWSER_REDIRECT_URL = http://:9080/console + location /console/ { + 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_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_set_header X-NginX-Proxy true; + chunked_transfer_encoding off; + proxy_pass http://minio_console; + } + + # S3 API (endpoint) на корне — Range/стриминг крупных объектов. + # Путь не переписываем, иначе ломается подпись SigV4. + location / { + 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_http_version 1.1; + proxy_set_header Connection ""; + proxy_set_header Range $http_range; + proxy_set_header If-Range $http_if_range; + proxy_buffering off; + proxy_request_buffering off; + proxy_max_temp_file_size 0; + proxy_pass http://minio_s3; + } +}