Nginx 가상 호스트: 단일 서버에서 여러 웹사이트 호스팅
현대의 웹 인프라에서는 단일 서버 인스턴스에서 여러 웹사이트 또는 웹 애플리케이션을 제공할 수 있는 기능이 자주 요구됩니다. 이는 리소스 활용을 최적화할 뿐만 아니라 관리 및 운영 비용을 절감하고 단순화합니다. 높은 성능, 안정성, 풍부한 기능 세트 및 낮은 리소스 소비로 알려진 Nginx는 이를 서버 블록이라고 부르는 것을 통해 달성하며, 이는 Apache 환경에서는 종종 가상 호스트라고도 불립니다.
이 포괄적인 가이드에서는 단일 Nginx 서버에서 여러 개의 개별 도메인 이름 또는 하위 도메인을 효과적으로 관리하고 제공하기 위해 Nginx 가상 호스트를 설정하는 과정을 안내합니다. example.com과 anothersite.org를 호스팅하든, blog.example.com 및 shop.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로 표시된 블록)으로 대체됩니다.
사전 요구 사항
시작하기 전에 다음 사항을 확인하세요:
- Nginx 설치: 서버에 Nginx가 설치되어 실행 중이어야 합니다. 그렇지 않은 경우 일반적으로 시스템의 패키지 관리자(예: Ubuntu/Debian의
sudo apt update && sudo apt install nginx, CentOS/RHEL의sudo yum install nginx)를 통해 설치할 수 있습니다. - 도메인 이름: 호스팅하려는 도메인 이름(예:
example1.com및example2.com) 또는 하위 도메인(예:blog.example.com및app.example.com)이 최소 두 개 필요합니다. 이러한 도메인의 DNS A/AAAA 레코드는 서버의 공개 IP 주소를 가리켜야 합니다. - 기본 디렉터리 구조: 웹사이트 파일이 저장될 위치에 대한 계획. 일반적인 관행은
/var/www/yourdomain.com/html입니다. - Sudo 권한: Nginx 구성 파일을 수정하려면
sudo액세스가 필요합니다.
단계별 설정 가이드
두 개의 가상 호스트 example1.com 및 example2.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_log및error_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.com 및 http://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_log 및 error_log 파일을 지정하는 것은 모범 사례입니다. 이렇게 하면 결합된 로그를 뒤지는 번거로움 없이 개별 웹사이트의 문제를 디버깅하고 트래픽을 분석하는 것이 훨씬 쉬워집니다.
구성 파일 구조
더 큰 배포의 경우 Nginx 구성 파일을 다음과 같이 구성하는 것을 고려하십시오:
nginx.conf: 주요 구성,conf.d/*.conf및sites-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의 리버스 프록시, 로드 밸런싱, 캐싱과 같은 기능을 추가로 탐색하여 웹 서버의 성능과 안정성을 향상시킬 수 있습니다.