정적 파일의 디스크 경로를 정하는 두 지시자. 동작이 정반대다.
location /images/ {
root /var/www; # → /var/www/images/logo.png
}
location /images/ {
alias /var/www/pics/; # → /var/www/pics/logo.png
}
- root — location 경로를 '뒤에 붙인다'
- 최종 경로 = root + 요청 URI
- alias — location 경로를 '대체한다'
- 최종 경로 = alias + (요청 URI - location 접두사)
alias 는 슬래시를 맞춰야 한다
location /images/ { alias /var/www/pics; } # ✗ 끝 슬래시 불일치
# /images/logo.png → /var/www/picslogo.png (경로가 어긋난다)
location /images/ { alias /var/www/pics/; } # ✓
location 이 슬래시로 끝나면 alias 도 슬래시로 끝나야 한다 둘 다 없거나 둘 다 있어야 한다 — 한쪽만 있으면 조용히 잘못된 경로가 된다 404 가 나면 error log 에 실제로 찾은 경로가 찍히므로 거기서 바로 보인다
정규식 location 에서는 alias 가 까다롭다
location ~ ^/images/(.*)$ {
alias /var/www/pics/$1; # 캡처를 명시해야 한다
}
캡처 그룹을 빠뜨리면 경로가 통째로 어긋난다. 가능하면 root 로 푼다 는 것이 실무 기본값이고, 디렉터리 구조를 URL 에 맞추는 편이 설정을 단순하게 만든다.
경로 탈출 주의
alias 와 정규식을 조합할 때 캡처에 ../ 가 들어가면 의도한 디렉터리 밖 파일이 노출될 수 있다
-
location 접두사를 슬래시로 끝맺는다
-
캡처에 경로 문자를 허용하지 않는 패턴을 쓴다
-
애초에 alias 대신 root 를 쓴다
-
과거에 alias 의 끝 슬래시 누락과 결합해 실제 취약점 사례가 있었다
함께 쓰는 지시자
location /images/ {
root /var/www;
try_files $uri =404; # 없으면 404 (아래로 흘려보내지 않는다)
expires 30d;
access_log off; # 정적 자산 로그는 대개 잡음이다
}
- autoindex on; — 디렉터리 목록을 보여 준다 — 운영에서는 켜지 않는다
- 내부 파일 구조가 그대로 노출된다
정적 파일을 앞단에서 주는 이유
같은 파일을 WAS 가 주는 것보다 훨씬 싸다
- sendfile 로 커널 안에서 바로 전송 (복사·모드 전환 감소)
- open_file_cache 로 파일 메타데이터를 캐시
- 애플리케이션 스레드를 전혀 안 쓴다
open_file_cache max=10000 inactive=60s; open_file_cache_valid 60s; open_file_cache_min_uses 2; open_file_cache_errors on;
파일 수가 많은 사이트에서 stat() 호출이 눈에 띄게 준다
컨테이너에서 자주 어긋나는 것
- 이미지에 정적 파일이 안 들어갔다 → 404
- 빌드 산출물 복사 단계를 확인한다
- 볼륨 마운트 경로가 root 와 다르다
- 파일 권한 — nginx 워커 사용자가 읽을 수 있어야 한다
- error log 에 "Permission denied" 가 찍힌다
404 가 나면 error log 를 먼저 본다 — 실제로 어느 경로를 찾았는지가 그대로 적혀 있다
면접 함정
- ❌ "root와 alias는 같은 것" → 붙이느냐 대체하느냐가 다르다.
- ❌ "슬래시는 취향" → alias에서는 경로가 어긋나고 보안 문제로도 이어진다.