웹 서버를 설정하다 보면 의도와 다르게 동작하여 당황스러운 경우가 발생할 수 있습니다. 특히 Nginx의 location 블록은 매칭 규칙과 우선순위가 복잡하여 예상치 못한 결과를 초래하기도 합니다. location 블록의 우선순위 문제로 인해 특정 경로에서 404 오류가 발생한 사례를 공유하고, 이를 해결한 방법을 소개하겠습니다.
다음과 같이 Nginx 설정을 구성했습니다:
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
location ~* \.(css|js|png|jpg|jpeg|gif|ico)$ {
expires 1M;
access_log off;
add_header Cache-Control "public";
}
location /static/ {
alias /var/www/html/static/;
}
}
웹 사이트의 정적 파일을 /static/ 경로를 통해 제공하기 위해 /var/www/html/static/ 디렉토리에 파일을 배치했습니다. 그러나 http://example.com/static/style.css에 접근하면 404 오류가 발생했습니다.
위 설정에서 /static/ 경로에 대한 location 블록을 추가했지만, 요청이 예상대로 처리되지 않았습니다.
Nginx의 location 매칭 우선순위로 인해 /static/style.css 요청은 다음과 같이 처리됩니다:
/static/style.css는 정규식 location ~* \.(css|js|png|jpg|jpeg|gif|ico)$ 블록에 매칭됩니다.root나 alias 지시어가 없기 때문에 기본 root 디렉토리에서 파일을 찾습니다./var/www/html/static/ 디렉토리에 있으므로, Nginx는 해당 파일을 찾지 못하고 404 오류를 반환합니다.즉, 정규식 location 블록이 /static/ 블록보다 우선하여 매칭되기 때문에 발생한 문제입니다.
/static/ 경로의 요청이 정규식 블록보다 우선하도록 location 블록의 우선순위를 조정하고, 파일이 올바른 경로에서 제공되도록 설정을 수정해야 합니다.
^~ 수정자를 사용하여 우선순위 지정/static/ 경로의 location 블록에 ^~ 수정자를 추가합니다:
location ^~ /static/ {
alias /var/www/html/static/;
}
^~ 수정자를 사용하면 이 location 블록이 정규식 매칭보다 우선적으로 매칭됩니다.
수정된 설정은 다음과 같습니다:
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.html;
location ^~ /static/ {
alias /var/www/html/static/;
}
location / {
try_files $uri $uri/ =404;
}
location ~* \.(css|js|png|jpg|jpeg|gif|ico)$ {
expires 1M;
access_log off;
add_header Cache-Control "public";
}
}
이렇게 수정하면 /static/ 경로의 요청은 location ^~ /static/ 블록에 매칭되어 파일이 정상적으로 제공됩니다.
설정을 수정한 후, Nginx 설정 파일의 문법 오류를 검사합니다:
sudo nginx -t
이후 Nginx를 재시작하거나 설정을 재로드합니다:
sudo nginx -s reload
또는
sudo systemctl reload nginx
이제 http://example.com/static/style.css에 접근하면 파일이 정상적으로 제공되는 것을 확인할 수 있습니다.
=): 요청 URI와 정확히 일치하는 블록.^~): 지정한 경로로 시작하는 URI를 매칭하며, 정규식 매칭보다 우선합니다.~, ~*): 정규식을 사용하여 URI를 매칭합니다.alias 지시어 사용 시 슬래시(/) 처리에 주의: location이 슬래시로 끝나면 alias도 슬래시로 끝나야 합니다.