Nginx 가상 호스트: 하나의 서버에서 여러 웹사이트 호스팅하기

단일 서버에서 여러 웹사이트 또는 하위 도메인을 효율적으로 호스팅하기 위해 Nginx 가상 호스트(서버 블록)의 강력한 기능을 활용하세요. 이 가이드는 디렉터리 설정, 구성 파일 생성, 서버 블록 활성화 및 Nginx 테스트를 다루는 포괄적인 단계별 튜토리얼을 제공합니다. 하위 도메인, 기본 서버 블록, HTTPS 통합 및 전용 로깅에 대한 모범 사례를 알아보세요. 실용적인 예제와 필수 문제 해결 팁을 통해 다중 사이트 Nginx 호스팅을 마스터하고 리소스 사용을 최적화하며 웹 서버 관리를 간소화할 수 있습니다.

38 조회수

Nginx 가상 호스트: 단일 서버에서 여러 웹사이트 호스팅

현대의 웹 인프라에서는 단일 서버 인스턴스에서 여러 웹사이트 또는 웹 애플리케이션을 제공할 수 있는 기능이 자주 요구됩니다. 이는 리소스 활용을 최적화할 뿐만 아니라 관리 및 운영 비용을 절감하고 단순화합니다. 높은 성능, 안정성, 풍부한 기능 세트 및 낮은 리소스 소비로 알려진 Nginx는 이를 서버 블록이라고 부르는 것을 통해 달성하며, 이는 Apache 환경에서는 종종 가상 호스트라고도 불립니다.

이 포괄적인 가이드에서는 단일 Nginx 서버에서 여러 개의 개별 도메인 이름 또는 하위 도메인을 효과적으로 관리하고 제공하기 위해 Nginx 가상 호스트를 설정하는 과정을 안내합니다. example.comanothersite.org를 호스팅하든, blog.example.comshop.example.com과 같은 하위 도메인이 있는 메인 사이트를 호스팅하든, Nginx 서버 블록을 숙달하는 것은 모든 시스템 관리자 또는 개발자에게 기본적인 기술입니다. 이 글을 마치면 Nginx 서버를 다중 사이트 호스팅용으로 구성하기 위한 명확한 이해와 실질적인 예제를 갖게 될 것입니다.

Nginx 서버 블록 (가상 호스트) 이해하기

핵심적으로 Nginx 서버 블록은 Nginx 구성 파일(nginx.conf 또는 포함된 파일) 내에 정의된 구성 지시어입니다. 각 server 블록은 특정 가상 호스트에 대한 구성을 정의하며, Nginx가 특정 도메인 또는 도메인 집합에 대한 요청에 어떻게 응답해야 하는지를 지정합니다. Nginx는 listen 지시어를 사용하여 수신할 IP 주소와 포트를 지정하고, server_name 지시어를 사용하여 이 서버 블록이 응답해야 하는 도메인 이름 또는 호스트 이름을 식별합니다.

요청이 들어오면 Nginx는 HTTP 요청의 Host 헤더를 검사하고 구성된 서버 블록의 server_name 지시어와 비교합니다. 그런 다음 일치하는 서버 블록에 정의된 콘텐츠를 제공합니다. server_name이 일치하지 않으면 Nginx는 일반적으로 기본 서버 블록(첫 번째 server 블록 또는 명시적으로 default_server로 표시된 블록)으로 대체됩니다.

사전 요구 사항

시작하기 전에 다음 사항을 확인하세요:

  1. Nginx 설치: 서버에 Nginx가 설치되어 실행 중이어야 합니다. 그렇지 않은 경우 일반적으로 시스템의 패키지 관리자(예: Ubuntu/Debian의 sudo apt update && sudo apt install nginx, CentOS/RHEL의 sudo yum install nginx)를 통해 설치할 수 있습니다.
  2. 도메인 이름: 호스팅하려는 도메인 이름(예: example1.comexample2.com) 또는 하위 도메인(예: blog.example.comapp.example.com)이 최소 두 개 필요합니다. 이러한 도메인의 DNS A/AAAA 레코드는 서버의 공개 IP 주소를 가리켜야 합니다.
  3. 기본 디렉터리 구조: 웹사이트 파일이 저장될 위치에 대한 계획. 일반적인 관행은 /var/www/yourdomain.com/html입니다.
  4. Sudo 권한: Nginx 구성 파일을 수정하려면 sudo 액세스가 필요합니다.

단계별 설정 가이드

두 개의 가상 호스트 example1.comexample2.com을 설정해 보겠습니다.

1단계: 웹사이트 디렉터리 구조 생성

먼저 각 웹사이트에 대한 루트 디렉터리를 생성합니다. 이곳에 HTML, CSS, JavaScript 및 기타 정적 파일이 저장됩니다. 일반적인 위치는 /var/www/입니다.

sudo mkdir -p /var/www/example1.com/html
sudo mkdir -p /var/www/example2.com/html

# 편집을 허용하기 위해 소유권을 사용자에게 설정 ( $USER 를 사용자 이름으로 바꾸세요)
sudo chown -R $USER:$USER /var/www/example1.com/html
sudo chown -R $USER:$USER /var/www/example2.com/html

# 웹 서버에 대한 읽기 권한 설정
sudo chmod -R 755 /var/www

다음으로, 설정을 테스트하기 위해 각 디렉터리에 간단한 index.html 파일을 생성합니다:

/var/www/example1.com/html/index.html의 경우:

<!-- /var/www/example1.com/html/index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Welcome to Example1.com!</title>
</head>
<body>
    <h1>Success! This is Example1.com.</h1>
    <p>This virtual host is working correctly.</p>
</body>
</html>

/var/www/example2.com/html/index.html의 경우:

<!-- /var/www/example2.com/html/index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Welcome to Example2.com!</title>
</head>
<body>
    <h1>Success! This is Example2.com.</h1>
    <p>This virtual host is also working!</p>
</body>
</html>

2단계: Nginx 서버 블록 구성 파일 생성

Nginx는 일반적으로 /etc/nginx/sites-enabled/ 디렉터리의 서버 블록 구성 파일을 로드합니다. 이러한 파일은 일반적으로 /etc/nginx/sites-available/에 저장된 구성에 대한 심볼릭 링크입니다. 이 분리를 통해 아직 활성화되지 않은 구성을 저장하거나 사이트를 쉽게 활성화/비활성화할 수 있습니다.

example1.com에 대한 새 구성 파일을 생성합니다:

sudo nano /etc/nginx/sites-available/example1.com.conf

다음 내용을 추가합니다:

# /etc/nginx/sites-available/example1.com.conf
server {
    listen 80;
    listen [::]:80;

    root /var/www/example1.com/html;
    index index.html index.htm index.nginx-debian.html;

    server_name example1.com www.example1.com;

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

    access_log /var/log/nginx/example1.com_access.log;
    error_log /var/log/nginx/example1.com_error.log;
}

지시어 설명:

  • listen 80;: Nginx는 포트 80(표준 HTTP)에서 수신 대기합니다. listen [::]:80;은 IPv6용입니다.
  • root /var/www/example1.com/html;: 이 서버 블록의 문서 루트를 지정합니다. Nginx는 이 디렉터리 내에서 파일을 찾습니다.
  • index index.html ...;: 디렉터리가 요청될 때(예: example1.com/ 방문 시) Nginx가 제공해야 하는 기본 파일을 정의합니다.
  • server_name example1.com www.example1.com;: 이것이 중요합니다. Nginx가 example1.com 또는 www.example1.com에 대한 요청에 이 서버 블록의 구성을 사용하여 응답하도록 지시합니다.
  • location / { ... }: 특정 URI에 대한 요청을 처리하는 방법을 정의하는 블록입니다. try_files는 파일을 직접($uri) 제공하려고 시도한 다음 디렉터리($uri/)를 제공하고 마지막으로 404 Not Found 오류를 반환합니다.
  • access_logerror_log: 각 사이트에 대한 별도의 로그 파일을 지정하며, 이는 디버깅 및 분석을 더 쉽게 하기 위한 좋은 관행입니다.

이제 example2.com에 대해 유사한 구성 파일을 생성합니다:

sudo nano /etc/nginx/sites-available/example2.com.conf

다음 내용을 추가합니다:

# /etc/nginx/sites-available/example2.com.conf
server {
    listen 80;
    listen [::]:80;

    root /var/www/example2.com/html;
    index index.html index.htm index.nginx-debian.html;

    server_name example2.com www.example2.com;

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

    access_log /var/log/nginx/example2.com_access.log;
    error_log /var/log/nginx/example2.com_error.log;
}

3단계: 서버 블록 활성화

이러한 구성을 활성화하려면 sites-available 디렉터리에서 sites-enabled 디렉터리로 심볼릭 링크를 만듭니다. 이렇게 하면 Nginx가 시작될 때 이러한 파일을 포함하도록 Nginx에 지시합니다.

sudo ln -s /etc/nginx/sites-available/example1.com.conf /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/example2.com.conf /etc/nginx/sites-enabled/

4단계: Nginx 구성 테스트

다시 로드하기 전에 구문 오류에 대해 Nginx 구성을 테스트하는 것이 중요합니다. 이렇게 하면 오타로 인해 Nginx가 다시 시작되지 못하는 것을 방지할 수 있습니다.

sudo nginx -t

성공을 나타내는 다음과 유사한 출력을 보게 될 것입니다:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

오류가 표시되면 해당 구성 파일에서 수정하고 sudo nginx -t를 다시 실행하여 통과할 때까지 확인합니다.

5단계: Nginx 재시작

Nginx를 재시작하거나 다시 로드하여 새 구성을 적용합니다. reload는 Nginx가 활성 연결을 끊지 않고 새 구성을 로드할 수 있도록 하므로 일반적으로 선호됩니다.

sudo systemctl reload nginx
# 또는 reload가 작동하지 않거나 새로 설치한 경우:
sudo systemctl restart nginx

6단계: DNS 레코드 업데이트

example1.com, www.example1.com, example2.com, www.example2.com에 대한 DNS A 레코드가 모두 Nginx 서버의 IP 주소를 가리키는지 확인합니다. 올바른 DNS 항목이 없으면 브라우저는 웹사이트를 찾을 위치를 알 수 없습니다.

DNS 전파가 완료되면(몇 분에서 몇 시간까지 걸릴 수 있음) 웹 브라우저에서 http://example1.comhttp://example2.com을 방문하여 해당 index.html 페이지를 볼 수 있어야 합니다.

고급 시나리오 및 모범 사례

하위 도메인 호스팅

하위 도메인(예: blog.example.com, shop.example.com)을 호스팅하는 것은 별도의 도메인을 호스팅하는 것과 정확히 동일하게 작동합니다. 하위 도메인을 server_name으로 하는 새 서버 블록을 정의하기만 하면 됩니다.

blog.example.com의 예:

# /etc/nginx/sites-available/blog.example.com.conf
server {
    listen 80;
    listen [::]:80;

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

    server_name blog.example.com;

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

디렉터리(/var/www/blog.example.com/html)를 생성하고, index.html을 생성하고, 심볼릭 링크를 생성하고, Nginx를 다시 로드하는 것을 잊지 마세요.

기본 서버 블록

서버의 다른 server_name 지시어와 일치하지 않는 도메인 이름에 대한 요청을 처리하는 기본 서버 블록을 갖는 것이 좋습니다. 이렇게 하면 알 수 없는 요청이 Nginx가 찾는 "첫 번째" 가상 호스트에 의해 제공되는 것을 방지하거나 일반 "사이트를 찾을 수 없음" 페이지를 제공할 수 있습니다.

일반적으로 nginx.conf 또는 sites-enabled의 첫 번째 server 블록은 암시적으로 기본값입니다. default_server를 사용하여 명시적으로 설정할 수 있습니다.

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name _;
    # 밑줄 `_`는 실제 요청과 일치하지 않는 존재하지 않는 도메인 이름입니다.
    # localhost를 사용할 수도 있습니다.

    root /var/www/default_site/html;
    index index.html;

    location / {
        return 444; # 알 수 없는 호스트에 대해 Nginx 특정 444 오류(응답 없음) 반환
        # 또는 일반 랜딩 페이지 제공:
        # try_files $uri $uri/ =404;
    }
}

경고: default_server 블록을 정의하는 경우, 주어진 listen 포트에서 default_server 플래그가 있는 server 블록이 하나만 있는지 확인하십시오. 그렇지 않으면 Nginx가 경고를 기록합니다.

HTTPS (SSL/TLS)를 사용한 가상 호스트 보안

운영 웹사이트의 경우 HTTPS를 활성화하는 것이 필수적입니다. 여기에는 SSL/TLS 인증서(예: Certbot을 사용한 Let's Encrypt)를 얻고 Nginx를 구성하여 인증서와 함께 포트 443에서 수신 대기하는 것이 포함됩니다.

일반적인 HTTPS 서버 블록은 다음과 같습니다(인증서를 얻은 후):

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name example1.com www.example1.com;

    root /var/www/example1.com/html;
    index index.html;

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

    # 기타 SSL 구성 포함 (암호, 프로토콜 등)
    include /etc/nginx/snippets/ssl-params.conf;
    include /etc/nginx/snippets/force-ssl.conf; # 선택 사항: HTTP를 HTTPS로 리디렉션

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

# 선택 사항: 이 도메인에 대한 HTTP에서 HTTPS로 리디렉션
server {
    listen 80;
    listen [::]:80;
    server_name example1.com www.example1.com;
    return 301 https://$host$request_uri;
}

트래픽을 HTTPS 버전으로 리디렉션하는 것만을 목적으로 하는 별도의 HTTP 서버 블록을 갖는 것이 일반적입니다.

각 사이트별 로깅

예제에서 볼 수 있듯이 각 가상 호스트에 대해 별도의 access_logerror_log 파일을 지정하는 것은 모범 사례입니다. 이렇게 하면 결합된 로그를 뒤지는 번거로움 없이 개별 웹사이트의 문제를 디버깅하고 트래픽을 분석하는 것이 훨씬 쉬워집니다.

구성 파일 구조

더 큰 배포의 경우 Nginx 구성 파일을 다음과 같이 구성하는 것을 고려하십시오:

  • nginx.conf: 주요 구성, conf.d/*.confsites-enabled/* 포함.
  • conf.d/: 일반적인 서버 전체 설정(예: Gzip, 캐싱).
  • snippets/: 재사용 가능한 Nginx 구성 스니펫(예: SSL 매개변수, 일반 location 블록).
  • sites-available/: 각 웹사이트에 대한 개별 server 블록.
  • sites-enabled/: sites-available/의 활성 구성에 대한 심볼릭 링크.

일반적인 문제 해결

  • 403 Forbidden 오류: 일반적으로 Nginx가 웹사이트 파일 또는 디렉터리에 대한 읽기 권한이 없음을 의미합니다. 파일 및 디렉터리 권한을 다시 확인하십시오(예: sudo chmod -R 755 /var/www/yourdomain.com/html 및 Nginx 사용자(일반적으로 www-data 또는 nginx)가 해당 파일에 액세스할 수 있는지 확인).
  • 404 Not Found 오류: 서버 블록의 root 지시어가 올바른 디렉터리를 가리키고 index.html 파일이 해당 위치에 있는지 확인합니다. 또한 try_files가 올바르게 구성되었는지 확인하십시오.
  • 잘못된 사이트 로딩: 이는 종종 server_name 지시어의 문제일 수 있습니다. server_name이 액세스하려는 도메인 이름( www. 또는 하위 도메인 포함)과 정확히 일치하는지 확인합니다. 또한 DNS 레코드를 확인하십시오.
  • Nginx 시작/다시 로드 실패: Nginx를 다시 로드하거나 다시 시작하기 전에 항상 sudo nginx -t를 사용하여 구성을 테스트하십시오. 오류 메시지는 구문 오류가 발생한 줄과 파일을 정확히 알려줍니다.
  • DNS 문제: IP 주소로 사이트에 액세스할 수 있지만 도메인 이름으로는 액세스할 수 없다면 거의 확실히 DNS 문제입니다. dig 또는 nslookup을 사용하여 도메인의 A 레코드가 올바른 서버 IP를 가리키는지 확인하십시오.

결론

Nginx 가상 호스트(서버 블록)는 단일 서버에서 여러 웹사이트를 호스팅할 수 있는 강력하고 유연한 방법을 제공합니다. listen, server_name, root, location 지시어를 적절하게 사용하여 server 블록을 올바르게 구성하면 다양한 웹 속성을 효율적으로 관리할 수 있습니다. 이 접근 방식은 리소스를 보존할 뿐만 아니라 서버 관리를 중앙 집중화합니다.

이 가이드에 설명된 기본 지식과 실질적인 단계를 통해 이제 Nginx 서버에서 여러 도메인을 설정하고 관리할 준비가 되었습니다. 구성을 항상 테스트하고, HTTPS로 사이트를 보호하고, 강력하고 유지 관리 가능한 웹 환경을 위해 로깅 및 디렉터리 구조에 대한 모범 사례를 따르는 것을 잊지 마십시오. 여기에서 Nginx의 리버스 프록시, 로드 밸런싱, 캐싱과 같은 기능을 추가로 탐색하여 웹 서버의 성능과 안정성을 향상시킬 수 있습니다.