File size: 5,132 Bytes
c6303c6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# Đị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;
        }
    }
}