Nginx nhiều vấn đề vị trí


14

Tôi hiện đang cố gắng tách 3 ứng dụng từ một kho lưu trữ thành 3, nhưng vẫn giữ cấu trúc url, vì vậy về cơ bản các vị trí khác nhau trong cùng một tên miền phải được phân phối bởi các ứng dụng khác nhau.

Điều tôi đang vật lộn là một trong những ứng dụng cần phải là dự phòng cho các url không tồn tại, vì vậy nếu ứng dụng đầu tiên không khớp và ứng dụng thứ hai không phù hợp thì ứng dụng thứ ba sẽ xử lý yêu cầu

Cấu trúc tôi có là:

/ etc / nginx / sites-enable / main_site, ở đây, ngoài server_name và nhật ký tôi đã nhận include /etc/nginx/subsites-enabled/*, trong đó tôi có 3 tệp cấu hình, mỗi tệp cho một ứng dụng.

Mỗi trong số 3 tệp cấu hình chứa một khối vị trí.

Tôi đã thử tìm kiếm tiêu cực trong regex (về cơ bản là cố gắng mã hóa các url mà các ứng dụng khác xử lý) nhưng không thành công.

Vì vậy, để tóm tắt:

/ và / cộng đồng nên được phân phối bởi /etc/nginx/subsites-enables/example.org/home (một vài tập lệnh perl)

/ tin tức nên được gửi bởi /etc/nginx/subsites-enables/example.org/news (wordpress)

mọi thứ khác sẽ được phân phối bởi /etc/nginx/subsites-enables/example.org/app (ứng dụng bánh)

Các bit perl hoạt động tốt. Vấn đề tôi gặp phải là ứng dụng đang tiếp nhận tin tức (có thể là do nó phù hợp. *), Tôi đã thử nhiều tùy chọn khác nhau (tôi đã ở đây trong 2 ngày) nhưng không ai trong số họ giải quyết được tất cả các vấn đề (đôi khi tài sản tĩnh sẽ không hoạt động, vv).

Cấu hình của tôi là:

/etc/nginx/sites-enables/example.org:

server {
    listen   80;
    server_name example.org;
    error_log /var/log/nginx/example.org.log;

    include /etc/nginx/subsites-enabled/example.org/*;
}

/etc/nginx/subsites-enables/example.org/home:

location = / {
  rewrite ^.*$ /index.pl last;
}

location ~* /community(.*) {
  rewrite ^.*$ /index.pl last;
}

location ~ \.pl {
  root   /var/www/vhosts/home;
  access_log /var/log/nginx/home/access.log;
  error_log /var/log/nginx/home/error.log;

  include /etc/nginx/fastcgi_params;
  fastcgi_index index.pl;
  fastcgi_param SCRIPT_FILENAME /var/www/vhosts/home$fastcgi_script_name;
  fastcgi_pass  unix:/var/run/fcgiwrap.socket;
}

/ etc / ngins / subsites-enable / news

location /news {
  access_log /var/log/nginx/news/access.log;
  error_log /var/log/nginx/news/error.log debug;

  error_page 404 = /news/index.php;

  root /var/www/vhosts/news;

  index index.php;

  if (!-e $request_filename) {
      rewrite ^.*$ /index.php last;
  }

  location ~ \.php {
    include /etc/nginx/fastcgi_params;
    fastcgi_pass  127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /var/www/vhosts/news$fastcgi_script_name;
  }
}

/ etc / nginx / subsites-enable / app:

location ~ .* {
  access_log /var/log/nginx/app/access.log;
  error_log /var/log/nginx/app/error.log;

  rewrite_log on;

  index index.php;
  root /var/www/vhosts/app/app/webroot;

  if (-f $request_filename) {
    expires 30d;
    break;
  }

  if (!-e $request_filename) {
    rewrite ^.*$ /index.php last;
  }

  location ~ \.php {
    include /etc/nginx/fastcgi_params;
    fastcgi_pass  127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /var/www/vhosts/app/app/webroot$fastcgi_script_name;
  }
}

a) đăng cấu hình của bạn cùng với một số ví dụ về nơi chuyển hướng khác nhau (bao gồm cả các URL cho các URL không tồn tại) sẽ đi. b) sử dụng try_files với khối vị trí được đặt tên (sử dụng @tiền tố) ánh xạ tới ứng dụng mặc định của bạn. Bạn cũng có thể thiết lập error_page ánh xạ 404 đến một vị trí được đặt tên.
cyberx86

@ cyberx86 Tôi đã thêm chi tiết và cấu hình của mình
Andrei Serdeliuc 17/212

Nhìn lướt qua gợi ý một số điều: a) kết hợp regex được ưu tiên hơn các chuỗi thông thường - vì vậy khối ứng dụng của bạn sẽ khớp thay vì khối tin tức của bạn - hãy thử location ^~ /news. b) đối với khối ứng dụng của bạn, bạn sẽ có thể thực hiện location /(điều này không giống với location = /, nhưng phải khớp với mọi thứ chưa khớp. c) trong một số trường hợp (đặc biệt là regexes), thứ tự không thành vấn đề - bạn có thể muốn kết hợp cả 3 tập tin thành một tập tin duy nhất với các khối theo đúng thứ tự. Ngoài ra, sử dụng try_files thay vì !-e. Cuối cùng, xem wiki.nginx.org/HttpCoreModule#location .
cyberx86

Tôi đã thử khá nhiều biến thể của chúng, bao gồm cả việc kết hợp chúng thành một tệp duy nhất (mặc dù chúng cần được tách riêng khi chúng được triển khai riêng), không có cái nào trong số chúng hoạt động. Tin tức chỉ được xử lý bởi các ứng dụng.
Andrei Serdeliuc

Chà, tôi nghĩ đã giải quyết nó - một chút khó khăn hơn tôi dự kiến ​​ban đầu - nhưng chắc chắn rất thú vị để phù hợp với trí thông minh chống lại. Cảm ơn vì câu đố.
cyberx86

Câu trả lời:


45

Có một vài điều sai với cấu hình của bạn, hai cái có liên quan là:

  1. Các đường dẫn trong một khối vị trí vẫn bao gồm đường dẫn phù hợp.
  2. Viết lại với 'lần cuối' tiếp tục bằng cách xem qua tất cả các vị trí có sẵn cho một trận đấu (chúng thoát ra khỏi khối vị trí hiện tại).

Ví dụ: lấy URL example.org/news/test.htm

  • Các location /newskhối sẽ phù hợp với nó
  • Đường dẫn được sử dụng là sau đó /news/test.htm- điều này không thay đổi, chỉ vì nó nằm trong khối vị trí
  • Thêm đường dẫn vào document_root, bạn nhận được: /var/www/vhosts/news/news/test.htm
  • if (!-e $request_filename)Tuyên bố của bạn sẽ nắm bắt được tệp không tồn tại này
  • Bạn viết lại đường dẫn đến /index.php
  • Vì bạn đang sử dụng lastcác quy trình bắt đầu lại (thoát ra khỏi khối vị trí)
  • /index.phpbây giờ được bắt bởi location /app block.

Vấn đề được đề cập ở trên, với chỉ thị gốc, được giải quyết khi bạn đi đến khối vị trí ứng dụng của mình. Không giống như khối 'tin tức', nơi bạn có thể hình dung chỉ cần xóa 'tin tức' khỏi đường dẫn (vì nó sẽ được thêm lại), bạn không thể thực hiện điều này cho đường dẫn ứng dụng, kết thúc bằng 'webroot'.

Giải pháp nằm trong aliaschỉ thị. Điều này không thay đổi document_root, nhưng nó thay đổi đường dẫn tệp được sử dụng để phục vụ yêu cầu. Thật không may, rewritetry_filescó xu hướng cư xử một chút bất ngờ với alias.

Hãy bắt đầu với một ví dụ đơn giản - không có PHP - chỉ HTML và khối Perl của bạn - nhưng với cấu trúc thư mục khớp với của bạn (được thử nghiệm trên Nginx 1.0.12, CentOS 6):

server {
    server_name example.org;
    error_log /var/log/nginx/example.org.error.log notice;
    access_log /var/log/nginx/example.org.access.log;
    rewrite_log on;

    location = / {
        rewrite ^ /index.pl last;
    }

    location ^~ /community {
        rewrite ^ /index.pl last;
    }

    location ~ \.pl {
        root   /var/www/vhosts/home;

        [fastcgi_stuff...]
    }


    location ^~ /news {
        alias /var/www/vhosts/news;
        index index.htm;

        try_files $uri $uri/ /news/index.htm;
    }

    location ^~ /app {
        alias /var/www/vhosts/app/app/webroot;
        index index.htm;

        try_files $uri $uri/ /app/index.htm;
    }

    location / {
        rewrite ^/(.*) /app/$1 last;
    }
}
  • location = / - sẽ chỉ khớp với đường dẫn gốc
  • location ^~ /community - sẽ khớp với mọi đường dẫn bắt đầu với / cộng đồng
  • location ~ \.pl - sẽ khớp với tất cả các tệp có chứa .pl
  • location ^~ /news - sẽ khớp với mọi đường dẫn bắt đầu bằng / tin tức
  • location ^~ /app - sẽ khớp với mọi đường dẫn bắt đầu bằng / app
  • location / - sẽ khớp với tất cả các đường dẫn không khớp ở trên

Bạn sẽ có thể xóa ^~- nhưng nó có thể cải thiện hiệu suất một chút, vì nó dừng tìm kiếm sau khi tìm thấy kết quả khớp.

Mặc dù việc thêm các khối PHP trở lại là một vấn đề đơn giản, nhưng thật không may, có một khó khăn nhỏ - try_files(và viết lại của bạn) không kết thúc việc chuyển đường dẫn mong muốn đến khối vị trí lồng nhau - và sử dụng aliaskhi chỉ có phần mở rộng được chỉ định trong khối vị trí không hoạt động.

Một giải pháp là sử dụng các khối vị trí riêng biệt thực hiện chụp cùng với chỉ thị bí danh - nó không thanh lịch, nhưng theo như tôi có thể nói, nó hoạt động (một lần nữa, được thử nghiệm trên Nginx 1.0.12, CentOS 6 - của Tất nhiên, tôi đã không thiết lập CakePHP, Wordpress và Perl - Tôi chỉ sử dụng một vài tệp PHP và HTML trong mỗi thư mục)

server {
    server_name example.org;
    error_log /var/log/nginx/example.org.error.log notice;
    access_log /var/log/nginx/example.org.access.log;
    rewrite_log on;

    location = / {
        rewrite ^ /index.pl last;
    }

    location ^~ /community {
        rewrite ^ /index.pl last;
    }

    location ~ \.pl {
        root   /var/www/vhosts/home;
        access_log /var/log/nginx/home.access.log;
        error_log /var/log/nginx/home.error.log;
        include /etc/nginx/fastcgi_params;
        fastcgi_index index.pl;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass  unix:/var/run/fcgiwrap.socket;
    }

    location /news {
        access_log /var/log/nginx/news.access.log;
        error_log /var/log/nginx/news.error.log notice;
        alias /var/www/vhosts/news;
        index index.php;
        try_files $uri $uri/ /news/index.php;
    }

    location ~* ^/news/(.*\.php)$ {
        access_log /var/log/nginx/news.php.access.log;
        error_log /var/log/nginx/news.php.error.log notice;
        alias /var/www/vhosts/news/$1;
        try_files "" /news/index.php;
        include /etc/nginx/fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_NAME $1;
        fastcgi_param SCRIPT_FILENAME /var/www/vhosts/news/$1;
        fastcgi_pass  127.0.0.1:9000;
    }

    location /app {
        alias /var/www/vhosts/app/app/webroot;
        access_log /var/log/nginx/app.access.log;
        error_log /var/log/nginx/app.error.log notice;
        index index.php;
        try_files $uri $uri/ /app/index.php;
    }

    location ~* ^/app/(.*\.php)$ {
        access_log /var/log/nginx/news.access.log;
        error_log /var/log/nginx/news.error.log notice;
        alias /var/www/vhosts/app/app/webroot/$1;
        try_files "" /app/index.php;
        include /etc/nginx/fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_NAME $1;
        fastcgi_param SCRIPT_FILENAME /var/www/vhosts/app/app/webroot/$1;
        fastcgi_pass  127.0.0.1:9000;
    }

    location / {
        rewrite ^/(.*) /app/$1 last;
    }
}

Cấu hình trên, lấy cái đơn giản ở trên và thực hiện hai thay đổi:

  • Thêm hai khối vị trí:
    • location ~* ^/news/(.*\.php)$ - sẽ khớp với tất cả các tệp kết thúc bằng .php, với các đường dẫn bắt đầu bằng / news /
    • location ~* ^/app/(.*\.php)$ - sẽ khớp với tất cả các tệp kết thúc bằng .php, với các đường dẫn bắt đầu bằng / app /
  • Xóa ^~kết quả khớp - điều này là bắt buộc để hai khối vị trí được thêm vào có thể khớp với các đường dẫn (nếu không, việc khớp sẽ dừng trên khối / tin tức hoặc / ứng dụng).

Cần lưu ý rằng thứ tự khớp vị trí rất quan trọng ở đây:

  • Kết hợp chính xác trước (sử dụng =)
  • Trận đấu với ^~thứ hai
  • Kết hợp các khối regex
  • Chuỗi thông thường - chỉ khi không tìm thấy regex phù hợp

Một regex phù hợp sẽ thay thế một chuỗi thẳng!

Một điểm quan trọng được đề cập là khi các ảnh chụp được sử dụng với bí danh, toàn bộ URL được thay thế - không chỉ là thư mục hàng đầu. Thật không may, điều này có nghĩa $fastcgi_script_namelà để trống - vì vậy, tôi đã sử dụng $1ở trên thay thế.

Tôi chắc chắn bạn sẽ cần phải thực hiện một vài thay đổi, nhưng tiền đề cơ bản nên có chức năng. Bạn sẽ có thể tách các khối thành nhiều tệp khi cần - việc đặt hàng không ảnh hưởng đến cấu hình.


2
Anh bạn, tôi ước tôi có thể nâng cấp bạn 100 lần. Bạn thật tuyệt vời Cảm ơn!
Andrei Serdeliuc
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.