Nginx Location 블록 완벽 가이드: 웹 트래픽 라우팅

Nginx location 블록은 효율적인 웹 트래픽 라우팅의 핵심입니다. 이 종합 가이드는 5가지 매칭 수정자(접두사, 정확히 일치, 가장 긴 접두사, 정규식)를 설명하고 Nginx가 따르는 엄격한 처리 순서를 설명합니다. 실용적인 구성 예제를 통해 정적 자산 라우팅, API 호출 프록시, 보안 규칙 구현 방법을 배우세요. Location 블록을 마스터하는 것은 정확한 트래픽 제어, 빠른 서버 성능 및 강력한 구성 관리의 핵심입니다.

Nginx Location 블록 완벽 가이드: 웹 트래픽 라우팅

Nginx location 블록은 요청이 올바른 server 블록에 도달한 후에 수행할 작업을 결정합니다. 이 블록 덕분에 /static/app.css는 디스크에서 제공되고, /api/users는 애플리케이션으로 프록시되며, /.git/config는 민감한 정보가 유출되기 전에 차단될 수 있습니다.

location 블록에서 발생하는 대부분의 실수는 구문 오류가 아니라 우선순위 오류입니다. 정규식이 접두사 블록이 처리할 것으로 예상한 요청을 가로채는 경우, root 경로가 생각보다 더 많은 URI를 추가하는 경우, proxy_pass에 후행 슬래시가 있을 때와 없을 때 업스트림 URI가 다르게 재작성되는 경우 등이 있습니다. 아래 예제는 이러한 실제 실패 지점에 초점을 맞춥니다.

Location 블록의 역할과 구조

location 블록은 Nginx가 요청 URI(Request URI)에 따라 요청에 응답하는 방법을 정의합니다. 이러한 블록은 항상 server 블록 내에 중첩됩니다.

클라이언트가 요청(예: GET /images/logo.png)을 보내면 Nginx는 수신 server 블록 내에 정의된 모든 location 블록에 대해 요청 URI를 확인하여 파일 제공, 클라이언트 리디렉션, 애플리케이션 서버로의 요청 프록시 등 적절한 처리를 결정합니다.

기본 구문

구문은 수정자(또는 수정자 없음) 다음에 패턴(URI)이 옵니다:

location [modifier] [pattern] {
    # 구성 지시문 (예: root, index, proxy_pass)
}

Location 매칭 유형 이해 (수정자)

Nginx는 몇 가지 location 매칭 스타일을 제공합니다. 선택은 라우팅 정밀도와 Nginx가 핸들러를 선택하기 전에 수행하는 작업량에 영향을 미칩니다.

1. 접두사 매치 (수정자 없음)

이것은 기본 매치 유형입니다. Nginx는 요청 URI와 일치하는 가장 긴 시작 문자열을 검색합니다.

수정자 예제 동작 가장 적합한 사용 사례
(없음) location /blog/ /blog/로 시작하는 URI와 일치합니다 (예: /blog/post/1). 일반 목적, 사이트의 큰 섹션 정의.

예제:

location /docs/ {
    root /var/www/html/public;
    # URI가 /docs/manual.pdf인 경우 Nginx는 /var/www/html/public/docs/manual.pdf를 찾습니다.
}

2. 정확히 일치 (=)

이 수정자는 URI와 패턴 사이의 정확한 일치를 강제합니다. 일치하면 Nginx는 즉시 다른 위치 검색을 중지합니다. 이것은 가장 빠른 매치 유형입니다.

수정자 예제 동작 가장 적합한 사용 사례
= location = /favicon.ico /favicon.ico URI와만 정확히 일치합니다. 특정 자주 요청되는 파일 또는 기본 페이지 처리.

3. 가장 긴 접두사, 비정규식 (^~)

이것은 특수한 접두사 매치입니다. Nginx가 ^~를 사용하여 가장 긴 접두사 일치를 찾으면 정규식 location 블록 확인을 즉시 중지하여 효과적으로 재정의합니다.

수정자 예제 동작 가장 적합한 사용 사례
^~ location ^~ /assets/ /assets/로 시작하는 URI와 일치하고 느린 정규식 일치가 확인되지 않도록 방지합니다. 정적 자산을 빠르게 제공하고 자산 디렉토리가 예측 가능하게 처리되도록 합니다.

4. 대소문자 구분 정규식 (~)

이것은 Perl 호환 정규식(PCRE)을 사용하여 일치합니다. 접두사 일치보다 강력하지만 느립니다. 첫 번째로 일치하는 정규식 블록이 승리합니다.

수정자 예제 동작 가장 적합한 사용 사례
~ location ~ \.php$ .php로 끝나는 모든 URI와 일치합니다. 특정 파일 유형 처리 (예: PHP 스크립트를 PHP-FPM에 전달).

5. 대소문자 구분하지 않는 정규식 (~*)

~와 동일하지만 URI의 대소문자를 무시합니다.

수정자 예제 동작 가장 적합한 사용 사례
~* `location ~* .(jpg gif png)$`

중요한 Location 처리 순서

Nginx가 location 블록을 처리하는 순서를 이해하는 것은 예기치 않은 동작을 방지하는 데 중요합니다. Nginx는 구성 파일을 단순히 위에서 아래로 읽지 않습니다. 엄격한 계층 구조를 사용합니다:

  1. 정확히 일치 (=): Nginx는 먼저 모든 정확히 일치 블록을 확인합니다. 일치하는 항목이 발견되면 처리가 즉시 중지되고 요청은 해당 블록에 의해 처리됩니다.
  2. 가장 긴 접두사 후보: Nginx는 일반 접두사 위치와 ^~ 위치를 포함하여 가장 긴 일치 접두사 위치를 찾습니다.
  3. ^~에 대한 정규식 건너뛰기: 최상의 접두사 일치가 ^~를 사용하는 경우 Nginx는 이를 사용하고 정규식 확인을 건너뜁니다.
  4. 정규식 (~~*): 최상의 접두사가 ^~가 아닌 경우 Nginx는 구성 파일에 나타나는 순서대로 정규식 위치를 확인합니다. 첫 번째로 일치하는 정규식 블록이 승리합니다.
  5. 가장 긴 표준 접두사 일치: 정규식 일치가 없으면 Nginx는 이미 찾은 가장 긴 접두사 후보를 사용합니다. 많은 구성에서 location /는 최종 폴백입니다.

이것이 ^~ /static/이 일반적인 이유입니다. ^~가 없으면 나중에 location ~* \.(css|js)$와 같은 정규식이 /static/app.css에 대해 여전히 승리할 수 있습니다. 때로는 괜찮습니다. 때로는 전체 /static/ 디렉토리에 대해 예상했던 캐시 헤더, 루트 경로 또는 액세스 규칙을 우회합니다.

실용적인 구성 시나리오

1. 성능을 위한 정적 자산 우선 처리

Nginx가 정적 파일을 직접 빠르게 제공하고 느린 정규식 확인과 애플리케이션 서버의 불필요한 처리를 방지하려면 ^~ 수정자를 사용하십시오.

server {
    listen 80;
    server_name myapp.com;

    # 1. 메인 페이지에 대한 정확히 일치 (최고 우선순위)
    location = / {
        proxy_pass http://backend_app_server;
    }

    # 2. 정적 자산에 대한 빠른 처리, 정규식 확인 우회
    location ^~ /static/ {
        root /var/www/site;
        expires 30d;
    }

    # 3. 일반적인 미디어 파일에 대한 정규식
    location ~* \.(gif|ico|css|js)$ {
        root /var/www/site;
        expires 7d;
    }

    # 4. 기타 모든 동적 요청에 대한 폴백
    location / {
        proxy_pass http://backend_app_server;
    }
}

2. API 트래픽 라우팅 및 프록시

Nginx를 리버스 프록시로 사용할 때 location 블록은 트래픽을 올바른 업스트림 애플리케이션 서버로 전달합니다.

location /api/v1/ {
    # Nginx가 클라이언트 연결 설정을 존중하도록 합니다.
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;

    # /api/v1/로 시작하는 모든 트래픽을 백엔드 서비스로 라우팅
    proxy_pass http://api_backend_service/v1/;

    # proxy_pass에 URI가 있으면 Nginx는 일치하는 접두사를 대체합니다.
    # /api/v1/users는 업스트림에서 /v1/users가 됩니다.
}

후행 슬래시 동작은 테스트할 가치가 있습니다. 다음 두 예제는 다릅니다:

location /api/ {
    proxy_pass http://api_backend;
}

location /api/ {
    proxy_pass http://api_backend/;
}

첫 번째 형식은 /api/...를 포함한 원래 URI를 업스트림에 전달합니다. 두 번째 형식은 일치된 /api/ 접두사를 /로 대체합니다. 작은 구성 편집 후 업스트림이 갑자기 404를 반환하기 시작하면 앱을 탓하기 전에 이것을 확인하십시오.

3. 민감한 디렉토리 보호

Location 블록을 사용하여 구성 파일이나 .git과 같은 숨겨진 디렉토리와 같은 민감한 내부 디렉토리에 대한 외부 액세스를 차단할 수 있습니다.

# 점으로 시작하는 파일에 대한 액세스 차단 (숨겨진 파일)
location ~ /\.(ht|svn|git) {
    deny all;
    return 404; # 존재를 숨기기 위해 403 대신 404 반환
}

# 특정 구성 디렉토리에 대한 액세스 차단
location /app/config/ {
    deny all;
}

숨겨진 파일의 경우 많은 팀이 더 광범위한 거부 규칙을 사용합니다:

location ~ /\.(?!well-known/) {
    deny all;
    return 404;
}

예외는 ACME HTTP-01 인증서 챌린지와 같은 항목에 대해 /.well-known/을 계속 사용할 수 있도록 하면서 대부분의 점 파일을 차단합니다. 사이트가 다른 합법적인 점 접두사 경로를 제공하는 경우 신중하게 테스트하십시오.

보안 경고: alias vs root 사용

location 블록 내에서 파일 경로를 구성할 때 rootalias의 차이점을 염두에 두십시오.

  • root: 전체 요청 URI를 정의된 경로에 추가합니다. (예: location /images/ + root /data//data/images/filename.jpg가 됩니다.)
  • alias: URI의 일치된 부분을 정의된 경로로 대체합니다. 이는 location 블록이 정규식을 사용하거나 파일을 제공하기 전에 경로의 일부를 제거해야 할 때 종종 필요합니다. (예: location /static/ + alias /opt/app/files//opt/app/files/filename.jpg가 됩니다.)

4. 후행 슬래시 및 리디렉션 처리

디렉토리가 항상 후행 슬래시(/)로 끝나는 것과 같은 일관된 URL 구조를 적용하는 것이 바람직한 경우가 많습니다.

# 누락된 경우 디렉토리 경로에 후행 슬래시 강제
location ~* /[a-z0-9\-_]+$ {
    # URI가 파일과 일치하면 Nginx는 제공을 시도합니다. 그렇지 않으면 디렉토리로 처리합니다.
    # 요청된 URI가 디스크의 디렉토리에 매핑되는지 확인:
    if (-d $request_filename) {
        return 301 $uri/;
    }
}

Location 라우팅 디버깅에 좋은 방법

요청이 잘못된 위치에 도달하면 문제를 하나의 URL과 하나의 server 블록으로 축소하십시오. nginx -T를 실행하여 포함된 파일을 포함한 전체 렌더링된 구성을 확인한 다음 해당 URI와 일치할 수 있는 모든 location을 검색하십시오. 파일 내 순서가 중요하기 때문에 정규식 블록에 특히 주의하십시오.

정적 파일의 경우 Nginx가 root 또는 alias에서 빌드할 파일 시스템 경로를 확인하십시오. 프록시 요청의 경우 proxy_pass에 업스트림 이름 뒤에 URI 부분이 포함되어 있는지 확인하십시오. 그런 다음 nginx -t가 통과한 후에만 다시 로드하십시오.

Location 블록은 우선순위 규칙을 내재화하면 예측 가능하지만 구성이 복사하여 붙여넣기로 커지면 용서하지 않습니다. 작은 핫 경로에는 정확히 일치를 사용하고, 정규식 처리를 우회해야 하는 디렉토리에는 ^~를 사용하고, 패턴 일치가 실제로 필요한 경우에만 정규식을 사용하고, 명확한 폴백으로 일반 location /를 사용하십시오.