Nginx 서버 블록 이해하기: 일반적인 설정 질문

Nginx 서버 블록이 어떻게 작동하는지 이해하세요 — 요청이 올바른 도메인에 어떻게 매칭되는지, 블록 내부에 무엇이 들어가는지, 혼동 없이 멀티 사이트 설정을 구성하는 방법을 알아보세요.

Nginx 서버 블록 이해하기: 일반적인 설정 질문

Nginx 서버 블록을 이해하는 것은 Nginx 설정을 덜 신비롭게 만드는 가장 빠른 방법 중 하나입니다. 서버 블록은 어떤 사이트가 요청을 처리할지, 어떤 도메인 이름이 일치하는지, 어떤 파일이 제공되는지, 프록시 트래픽이 어디로 가는지를 결정합니다.

둘 이상의 도메인을 호스팅하거나, HTTP를 HTTPS로 리디렉션하거나, Nginx 뒤에서 앱을 실행하는 경우, 대부분의 라우팅은 서버 블록에서 시작됩니다.

Nginx 서버 블록이란 무엇인가요?

Nginx 서버 블록은 특정 주소, 포트 및 호스트 이름 조합에 대해 Nginx가 어떻게 응답해야 하는지를 정의하는 설정 섹션입니다.

기본 정적 사이트 서버 블록은 다음과 같습니다:

server {
    listen 80;
    server_name example.com www.example.com;

    root /var/www/example.com/public;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

이것은 Nginx에게 포트 80에서 수신 대기하고, example.comwww.example.com에 대한 요청을 일치시키고, public 디렉토리에서 파일을 제공하고, 파일을 찾을 수 없을 때 404를 반환하도록 지시합니다.

"서버 블록"이라는 이름은 Nginx에서 일반적입니다. Apache 사용자는 가상 호스트와 유사한 개념을 알고 있을 수 있습니다. 목적은 동일합니다: 하나의 웹 서버가 여러 사이트나 앱을 처리할 수 있도록 하는 것입니다.

서버 블록은 일반적으로 /etc/nginx/sites-available/에 저장되며 Debian 및 Ubuntu 시스템에서는 /etc/nginx/sites-enabled/로의 심볼릭 링크를 통해 활성화됩니다. 일부 배포판은 대신 /etc/nginx/conf.d/를 사용합니다. 정확한 레이아웃은 nginx.conf에 어떤 파일이 포함되어 있는지 아는 것보다 덜 중요합니다.

Nginx는 올바른 서버 블록을 어떻게 선택하나요?

Nginx 선택은 단계적으로 이루어집니다. 먼저 listen 지시문의 IP 주소와 포트를 고려합니다. 그런 다음 요청 호스트 이름을 server_name과 비교합니다.

일치하는 호스트 이름이 없으면 Nginx는 해당 주소와 포트에 대한 기본 서버를 사용합니다. 명시적으로 표시할 수 있습니다:

server {
    listen 80 default_server;
    server_name _;
    return 444;
}

일부 팀은 이와 같은 기본 블록을 사용하여 일치하지 않는 요청을 삭제합니다. 다른 팀은 일반 404를 반환합니다. 최선의 선택은 로깅 및 보안 선호도에 따라 다릅니다.

아직 배우고 있다면, return 444보다는 눈에 띄는 404 기본값이 디버깅하기 더 쉬울 수 있습니다. 444는 Nginx 특정 연결 종료이며 클라이언트 측에서 네트워크 문제처럼 보일 수 있기 때문입니다. 프로덕션에서는 일부 팀이 무작위 일치하지 않는 호스트에 대해 조용한 종료를 선호합니다. 팀이 이해한다면 어느 선택이든 괜찮습니다.

정확한 이름이 와일드카드 이름보다 선호됩니다. 예를 들어, api.example.com*.example.com보다 더 구체적입니다. 정규식 서버 이름도 가능하지만, 읽고 문제를 해결하기 어렵기 때문에 드물게 사용해야 합니다.

일반적인 실수는 DNS에 새 도메인을 추가했지만 server_name에 추가하는 것을 잊는 것입니다. 요청이 서버에 도달하지만 Nginx는 기본 블록으로 보냅니다. 사용자 관점에서는 잘못된 사이트가 나타나거나 요청이 실패합니다.

또 다른 일반적인 실수는 동일한 listenserver_name을 주장하는 두 개의 블록을 만드는 것입니다. Nginx는 충돌하는 서버 이름에 대해 경고하고 그 중 하나를 무시할 수 있습니다. 사이트를 추가한 후에는 항상 구성을 테스트하세요.

잘못된 사이트가 응답할 때 다음을 사용하세요:

sudo nginx -T | grep -n "server_name"
curl -I -H 'Host: example.com' http://127.0.0.1/

nginx -T는 포함된 파일을 포함한 전체 로드된 구성을 출력합니다. 이는 sites-enabled 아래의 모든 파일을 여는 것보다 종종 더 빠릅니다.

서버 블록 내부에는 무엇이 들어가나요?

서버 블록은 일반적으로 도메인 일치, TLS, 문서 루트, 로깅, 리디렉션 및 하나 이상의 location 블록에 대한 지시문을 포함합니다.

리버스 프록시의 경우 블록은 다음과 같을 수 있습니다:

server {
    listen 443 ssl;
    server_name app.example.com;

    ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://127.0.0.1:3000;
    }
}

여기서 Nginx는 HTTPS를 종료하고 트래픽을 포트 3000의 로컬 애플리케이션으로 전달합니다. 이는 Node.js, Python, Ruby, Go 및 Java 앱에서 일반적입니다.

업스트림 앱이 원래 체계나 클라이언트 IP를 알아야 하는 경우 해당 proxy_set_header 줄이 중요합니다. 그것들이 없으면 앱은 모든 요청이 일반 HTTP를 통해 127.0.0.1에서 온 것으로 생각할 수 있습니다. 이는 리디렉션, 감사 로그, 속도 제한 및 생성된 콜백 URL을 손상시킬 수 있습니다.

여러 사이트를 호스팅할 때 명확한 로그 경로를 사용하세요:

access_log /var/log/nginx/app.example.com.access.log;
error_log /var/log/nginx/app.example.com.error.log;

별도의 로그는 문제 해결을 훨씬 쉽게 만듭니다. 모든 사이트가 하나의 액세스 로그에 기록되면 어떤 도메인이 실패하고 있는지 파악하는 데 더 오래 걸립니다.

바쁜 호스트의 경우 이는 보존을 더 쉽게 만듭니다. 인시던트 중 API에 대한 상세 로그와 정적 사이트에 대한 가벼운 로깅이 필요할 수 있습니다. 파일을 분리하면 모든 서버 블록을 한 번에 변경하지 않고도 그 옵션을 얻을 수 있습니다.

서버 블록과 위치 블록은 어떻게 다른가요?

서버 블록은 사이트를 선택합니다. 위치 블록은 해당 사이트 내에서 경로로 무엇을 할지 선택합니다.

예를 들어:

server {
    server_name example.com;

    location /assets/ {
        expires 30d;
    }

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

    location / {
        try_files $uri $uri/ /index.html;
    }
}

/assets/logo.png에 대한 요청은 정적 파일 캐싱을 얻습니다. /api/users에 대한 요청은 업스트림 백엔드로 이동합니다. 다른 요청은 프론트엔드 앱으로 전달됩니다.

이 분할은 중요합니다. 잘못된 도메인이 응답하면 서버 블록 일치를 살펴보세요. 올바른 도메인이 응답하지만 잘못된 경로 동작이 발생하면 위치 일치를 살펴보세요.

이 구분은 시간을 절약합니다. api.example.com/users에 대한 요청은 api.example.com이 잘못된 서버 블록과 일치했거나 /users가 올바른 블록 내에서 잘못된 위치와 일치했기 때문에 실패할 수 있습니다. 이들은 다른 문제입니다.

경로 라우팅에 대한 자세한 내용은 Nginx 위치 블록 설명을 참조하세요.

여러 사이트를 어떻게 구성해야 하나요?

가능하면 사이트나 앱당 하나의 파일을 사용하세요. 각 파일에 도메인이나 목적과 일치하는 이름을 지정하세요:

/etc/nginx/sites-available/example.com
/etc/nginx/sites-available/api.example.com
/etc/nginx/sites-available/admin.example.com

이렇게 하면 검토가 더 쉬워지고 잘못된 서비스를 변경할 가능성이 줄어듭니다. 또한 사이트를 빠르게 비활성화해야 할 때 도움이 됩니다.

공유 스니펫을 작고 명확하게 유지하세요. TLS 설정, 프록시 헤더 및 보안 헤더는 포함하기 좋은 후보입니다. 일반적인 포함 파일에 주요 라우팅 동작을 숨기지 마세요. 디버깅이 더 어려워지기 때문입니다.

실용적인 설정은 다음을 포함할 수 있습니다:

include snippets/proxy-headers.conf;
include snippets/security-headers.conf;

반복을 줄이기 위해 포함을 사용하되 모든 사이트가 동일하게 동작하도록 만들지 마세요. 내부 관리 패널, 공개 API 및 정적 마케팅 사이트는 종종 다른 제한과 헤더가 필요합니다.

서버 블록 파일을 삭제하거나 이름을 바꾸기 전에 어떻게 포함되어 있는지 확인하세요. Debian 스타일 레이아웃에서 sites-available에서 파일을 제거해도 다른 복사본이 conf.d에 여전히 존재하면 아무 효과가 없습니다. 반면 sites-enabled에서 심볼릭 링크를 삭제하면 소스 파일을 삭제하지 않고 사이트가 비활성화됩니다.

ls -l /etc/nginx/sites-enabled/
sudo nginx -T | grep -n "include"

이 빠른 확인은 올바른 파일을 편집한 것처럼 보이지만 Nginx가 다른 파일을 계속 사용하는 좌절스러운 경우를 방지합니다.

서버 블록 문제에 대한 도움을 받아야 할 때

서버 블록 변경이 프로덕션 도메인, HTTPS 인증서, 고객 대면 리디렉션 또는 동일한 호스트의 여러 애플리케이션에 영향을 미칠 때 DevOps 엔지니어나 Nginx 전문가의 도움을 요청하세요. 작은 실수로 사용자가 잘못된 앱으로 이동하거나 인증서 갱신이 중단될 수 있습니다.

구성이 올바르다고 생각한 후에도 Nginx가 계속 잘못된 사이트를 제공하는 경우에도 도움을 받아야 합니다. 문제는 DNS, IPv6, 로드 밸런서, CDN 또는 눈치채지 못한 포함 파일과 관련될 수 있습니다.

서버 블록은 Nginx가 도메인 수준 트래픽을 라우팅하는 데 사용하는 지도입니다. 구체적으로 유지하고, 각 변경 후 테스트하고, 별도의 로그를 사용하고, 도메인 일치와 경로 라우팅을 정신적 모델에서 분리하세요. 이것이 이해되면 대부분의 Nginx 설정 질문에 답하기가 훨씬 쉬워집니다.