# Định nghĩa file lưu trữ Process ID (PID) của Nginx. # Đặt ở /run/ để đảm bảo user thường (không phải root) có quyền ghi sau khi được cấp phép ở Dockerfile. pid /run/nginx.pid; events { # Số lượng kết nối tối đa mà một worker process có thể xử lý cùng một lúc worker_connections 1024; } http { # Cấu hình bản đồ biến (map) để hỗ trợ kết nối WebSocket (Dành cho JupyterLab Terminal & Kernel real-time) # Nếu Header 'Upgrade' từ client gửi lên có giá trị, Nginx sẽ tự động nâng cấp kết nối sang WebSocket. map $http_upgrade $connection_upgrade { default upgrade; '' close; } # CẤU HÌNH DUNG LƯỢNG UPLOAD TỐI ĐA # Mặc định Nginx chỉ cho phép 1M. Dòng này nâng lên 1000M (1GB) để bạn upload file âm thanh, video, model AI thoải mái. client_max_body_size 10000M; server { # Cổng chính đón traffic từ môi trường Hugging Face Spaces listen 7860; # DNS nội bộ của Docker giúp Nginx phân giải các biến số proxy_pass động một cách chính xác resolver 127.0.0.11 valid=30s; # ======================================================================= # KHỐI 1: ĐIỀU HƯỚNG PORT ĐỘNG QUA URL (Ví dụ: /7861/, /8001/, /8002/...) # ======================================================================= # Regex kiểm tra nếu đường dẫn bắt đầu bằng một chuỗi số (4-5 chữ số) location ~ "^/(\d+)(.*)$" { # Tách số port từ URL nhóm 1 gán vào biến $target_port (Ví dụ: 7861) set $target_port $1; # Tách phần đường dẫn còn lại nhóm 2 gán vào biến $remaining_url (Ví dụ: /assets/main.js) set $remaining_url $2; # Tiến hành chuyển tiếp request về ứng dụng chạy ngầm ở port tương ứng proxy_pass http://127.0.0.1:$target_port$remaining_url$is_args$args; # Giữ nguyên thông tin Header gốc của người dùng gửi lên proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # ÉP CỨNG GIAO THỨC HTTPS: Sửa lỗi (blocked:mixed-content) trên trình duyệt. # Ép các framework như FastAPI/Gradio tự động sinh link file tĩnh dạng https:// thay vì http:// proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Scheme https; # Cấu hình giúp ứng dụng web nhận diện được nó đang chạy dưới một đường dẫn phụ (Sub-path) proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Prefix /$target_port; proxy_set_header X-Original-URI $request_uri; # Cấu hình bắt buộc để giữ kết nối WebSocket không bị ngắt quãng giữa chừng proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_read_timeout 86400; # Giữ kết nối tối đa 1 ngày (tránh sập kernel/terminal) } # ======================================================================= # KHỐI 2: MẶC ĐỊNH (ĐƯỜNG DẪN GỐC /) - JUPYTERLAB & NƠI VÁ FILE LẠC ĐƯỜNG # ======================================================================= location / { # --- CƠ CHẾ VÁ LỖI CÁC FILE TĨNH BỊ HARDCODE NHẢY VỀ GỐC --- # Nếu một file (như /theme.css) gọi trực tiếp về gốc nhưng Header 'Referer' chứng minh # nguồn gọi của nó xuất phát từ một trang chứa port phụ (Ví dụ: từ trang /7861/) if ($http_referer ~* /([0-9]+)/) { set $referer_port $1; # Nginx lẳng lặng "tóm" file đó gửi trả về đúng port phụ xử lý kèm theo đầy đủ URI ban đầu proxy_pass http://127.0.0.1:$referer_port$request_uri; } # --- MẶC ĐỊNH: ĐẨY TOÀN BỘ TRAFFIC CÒN LẠI VỀ JUPYTERLAB --- proxy_pass http://127.0.0.1:8888; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Ép giao thức HTTPS cho JupyterLab để đồng bộ bảo mật với Hugging Face proxy_set_header X-Forwarded-Proto https; # Cấu hình WebSocket dành riêng cho JupyterLab Terminal và Kernel chạy code proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_read_timeout 86400; } } }