Apache VirtualHost 설정
Apache의 VirtualHost는 하나의 서버에서 여러 도메인 또는 포트를 처리하는 기능입니다. Nginx의 server 블록에 해당합니다. 이름 기반, IP 기반, 포트 기반 구성과 SNI를 이용한 멀티 도메인 SSL까지 다룹니다.
VirtualHost 기본 구조
<VirtualHost IP주소:포트>
ServerName 도메인
DocumentRoot 웹루트경로
...
</VirtualHost>
IP주소 자리에 *를 쓰면 모든 IP에서 해당 포트로 들어오는 요청을 처리합니다.
이름 기반 VirtualHost (Name-Based)
동일한 IP·포트로 들어오는 요청을 Host 헤더의 도메인 이름으로 구분합니다. 가장 일반적인 방식입니다.
Ubuntu 설정 파일 만들기
# 사이트 설정 파일 생성
sudo nano /etc/apache2/sites-available/example.com.conf
# /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
ServerAdmin webmaster@example.com
<Directory /var/www/example.com>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/example.com.error.log
CustomLog ${APACHE_LOG_DIR}/example.com.access.log combined
</VirtualHost>
# 사이트 활성화
sudo a2ensite example.com.conf
# 설정 검증 + 리로드
sudo apache2ctl configtest && sudo systemctl reload apache2
CentOS 설정 파일 만들기
# /etc/httpd/conf.d/example.com.conf
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
<Directory /var/www/example.com>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog /var/log/httpd/example.com.error.log
CustomLog /var/log/httpd/example.com.access.log combined
</VirtualHost>
여러 사이트 동시 운영
# /etc/apache2/sites-available/site1.conf
<VirtualHost *:80>
ServerName site1.com
DocumentRoot /var/www/site1
ErrorLog ${APACHE_LOG_DIR}/site1.error.log
CustomLog ${APACHE_LOG_DIR}/site1.access.log combined
</VirtualHost>
# /etc/apache2/sites-available/site2.conf
<VirtualHost *:80>
ServerName site2.com
DocumentRoot /var/www/site2
ErrorLog ${APACHE_LOG_DIR}/site2.error.log
CustomLog ${APACHE_LOG_DIR}/site2.access.log combined
</VirtualHost>
# 두 사이트 모두 활성화
sudo a2ensite site1.conf site2.conf
sudo systemctl reload apache2
# 활성화된 사이트 목록 확인
sudo apache2ctl -S
포트 기반 VirtualHost
# /etc/apache2/ports.conf — 리슨 포트 추가
Listen 80
Listen 8080
# 메인 사이트 (80)
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/main
</VirtualHost>
# 관리자 포트 (8080) — 내부 접근만 허용
<VirtualHost *:8080>
ServerName example.com
DocumentRoot /var/www/admin
<Directory /var/www/admin>
Require ip 127.0.0.1 10.0.0.0/8
</Directory>
</VirtualHost>
HTTP → HTTPS 리다이렉트
# HTTP 가상 호스트 — HTTPS로 리다이렉트
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
# mod_rewrite를 이용한 HTTPS 리다이렉트
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>
# HTTPS 가상 호스트
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key
<Directory /var/www/example.com>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
또는 더 간결하게 Redirect 지시어 사용:
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://example.com/
</VirtualHost>
SSL VirtualHost와 SNI
SNI(Server Name Indication)를 이용하면 하나의 IP·443 포트에서 여러 도메인에 대해 각기 다른 SSL 인증서를 사용할 수 있습니다. Apache 2.2.12+, OpenSSL 0.9.8f+ 에서 지원합니다.
# 첫 번째 SSL 사이트
<VirtualHost *:443>
ServerName site1.com
DocumentRoot /var/www/site1
SSLEngine on
SSLCertificateFile /etc/ssl/certs/site1.com.crt
SSLCertificateKeyFile /etc/ssl/private/site1.com.key
</VirtualHost>
# 두 번째 SSL 사이트 (같은 포트, 다른 인증서)
<VirtualHost *:443>
ServerName site2.com
DocumentRoot /var/www/site2
SSLEngine on
SSLCertificateFile /etc/ssl/certs/site2.com.crt
SSLCertificateKeyFile /etc/ssl/private/site2.com.key
</VirtualHost>
기본(Default) VirtualHost
어떤 ServerName에도 매칭되지 않는 요청을 처리하는 기본 가상 호스트입니다. 목록의 첫 번째 VirtualHost가 기본값이 됩니다.
# 000-default.conf — 가장 먼저 로딩되도록 파일명 앞에 000 붙임
<VirtualHost *:80>
ServerName _default_
DocumentRoot /var/www/default
# 알 수 없는 도메인에 대해 403 반환
<Directory /var/www/default>
Require all denied
</Directory>
# 또는 특정 페이지로 리다이렉트
# Redirect 302 / https://www.example.com/
</VirtualHost>
가상 호스트 활성화/비활성화 (Ubuntu)
# 활성화
sudo a2ensite example.com.conf
# 비활성화
sudo a2dissite example.com.conf
# 전체 사이트 목록 (활성/비활성)
ls /etc/apache2/sites-available/
ls /etc/apache2/sites-enabled/
# 현재 가상 호스트 설정 요약
sudo apache2ctl -S
실전 예제: SPA + API 연동
React SPA를 서빙하면서 /api/ 요청은 Tomcat으로 프록시하는 설정입니다.
<VirtualHost *:443>
ServerName app.example.com
DocumentRoot /var/www/react-app/build
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/app.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/app.example.com/privkey.pem
<Directory /var/www/react-app/build>
Options -Indexes
AllowOverride None
Require all granted
# SPA 라우팅 — React Router 지원
FallbackResource /index.html
</Directory>
# 정적 에셋 캐시
<FilesMatch "\.(js|css|png|jpg|gif|ico|woff2)$">
Header set Cache-Control "max-age=31536000, public, immutable"
</FilesMatch>
# API 요청 → Tomcat 프록시
ProxyPreserveHost On
<Location "/api/">
ProxyPass http://127.0.0.1:8080/api/
ProxyPassReverse http://127.0.0.1:8080/api/
</Location>
</VirtualHost>
정리
| VirtualHost 유형 | 구분 기준 | 설정 핵심 |
|---|---|---|
| 이름 기반 | Host 헤더 (ServerName) | <VirtualHost *:80> + ServerName |
| 포트 기반 | listen 포트 | Listen 8080 + <VirtualHost *:8080> |
| SSL/SNI | ServerName + 인증서 | 같은 포트에서 도메인별 다른 인증서 |
| 기본 서버 | 매칭 없음 | 파일명 앞에 000 붙여 첫 번째 로딩 |