NGINX를 사용하여 기존의 모든 정적 파일을 직접 제공하지만 나머지는 백엔드 서버에 프록시하는 방법.


87
location / {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

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

    if (!-f $request_filename) {
        proxy_pass http://127.0.0.1:8080; # backend server listening
        break;
        }
    }

위는 Nginx를 사용하여 모든 기존 파일을 직접 제공합니다 (예 : Nginx는 PHP 소스 코드 만 표시). 그렇지 않으면 Apache에 요청을 전달합니다. * .php에 대한 요청도 Apache로 전달되고 처리되도록 규칙에서 * .php 파일을 제외해야합니다.

Nginx가 모든 정적 파일을 처리하고 Apache가 모든 동적 항목을 처리하기를 원합니다.

편집 : 화이트리스트 접근 방식이 있지만 매우 우아하지는 않습니다. 모든 확장 기능을 참조하십시오.

location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
    access_log off;
    expires 30d;
    }
location / {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
    }

편집 2 : Nginx의 최신 버전에서 try_files대신 http://wiki.nginx.org/HttpCoreModule#try_files 사용


정리하자면 위의 코드는 디스크에 존재하는 정적 파일을 제공하고 파일이 존재하지 않으면 Apache에 요청이 전달됩니다. 내 애플리케이션의 모든 URL이 mod_rewrite (또는 라우팅)를 사용하고 실제로 디스크에 존재하지 않기 때문에 이것은 대부분의 경우 작동합니다. * .php 파일 이름에 대한 직접 액세스 만 예외이며 Apache에서 구문 분석해야합니다.
fmalina

답변:


152

사용 try_files 및 명명 된 위치 블록 ( '@apachesite'). 이렇게하면 불필요한 정규식 일치 및 if 블록이 제거됩니다. 더 효율적입니다.

location / {
    root /path/to/root/of/static/files;
    try_files $uri $uri/ @apachesite;

    expires max;
    access_log off;
}

location @apachesite {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

업데이트 : 이 구성의 가정은 아래에 PHP 스크립트가 존재하지 않는다는 것 /path/to/root/of/static/files입니다. 이것은 대부분의 최신 PHP 프레임 워크에서 일반적입니다. 레거시 PHP 프로젝트에 php 스크립트와 정적 파일이 모두 같은 폴더에 혼합되어있는 경우 nginx에서 제공 할 모든 파일 유형을 허용 목록에 추가해야 할 수 있습니다.


워드 프레스를 사용하고 있는데 업로드 폴더를 nginx 서버에 넣어야하나요?
Chameron 2015-07-24

7
이 솔루션에 대한 내 문제 : nginx는 다른 위치 (프록시)를 사용하지 않고 디렉토리 목록을 표시하려고합니다. 따라서 디렉토리 목록이 활성화되지 않았기 때문에 403이 발생합니다. 편집 : 제거 $uri/하면 작동합니다.
ChristophLSA

1
이것은 / example을 아파치로 프록시하지만 /example.php가 다운로드되도록 허용합니다.
Terence Johnson

1
@TerenceJohnson 정적 파일 폴더 아래에 PHP 파일을 두는 것은 안전하지 않습니다. 내가 root /path/to/root/of/*static*/files;. php 파일은 인터넷에서 직접 액세스 할 수없는 다른 폴더에 넣어야합니다.
Chuan Ma

2
그게 그래야한다는 것을 알고 있지만, 누군가가 웹 루트 아래에 모든 것을 가지고 있고 .htaccess 파일에 의존하는 많은 일반적인 기성 PHP 애플리케이션 앞에 Nginx를 배치하고 있다면 복사해서는 안됩니다. 구성을 붙여 넣으십시오.
Terence Johnson

18

이 시도:

location / {
    root /path/to/root;
    expires 30d;
    access_log off;
}

location ~* ^.*\.php$ {
    if (!-f $request_filename) {
        return 404;
    }
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

잘하면 작동합니다. 정규식은 일반 문자열보다 우선 순위가 높으므로 .php해당 .php파일 만 존재 하는 경우 아파치로 끝나는 모든 요청을 인식 해야 합니다. 나머지는 정적 파일로 처리됩니다. 위치를 평가하는 실제 알고리즘은 여기에 있습니다 .


6

mod_rewrite를 사용하여 스크립트의 확장을 숨기거나 /로 끝나는 예쁜 URL이 마음에 들면 다른 방향에서 접근하는 것이 좋습니다. nginx에게 비 정적 확장을 가진 모든 것을 아파치로 보내도록 지시하십시오. 예를 들면 :

location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$
{
    root   /path/to/static-content;
}

location ~* ^!.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$ {
    if (!-f $request_filename) {
        return 404;
    }
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

http://code.google.com/p/scalr/wiki/NginxStatic 에서이 스 니펫의 첫 부분을 찾았습니다 .


축소 된 파일 (예 : site.min.css 및 main.min.js 등)에 대한 오류가 여전히 발생하지만 이것은 훌륭하게 작동했습니다. 위치 정규식에서 어떻게 잡을까요? @lo_fye
거스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.