Apache バーチャルホスト設定:1台のサーバーで複数のWebサイトをホストする

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

クイックスタート — 5分でApacheを起動する

Apacheをインストールしてページを配信したいだけ?最短の手順を紹介します。Ubuntu 22.04を使用していることを前提とします — 私が本番環境で使っている構成と同じです。

# Apacheをインストール
sudo apt update
sudo apt install apache2 -y

# 起動確認
sudo systemctl status apache2

# HTTPとHTTPS用のファイアウォールを開放
sudo ufw allow 'Apache Full'

ブラウザでhttp://your-server-ipにアクセスしてください。Apache2 Ubuntu Default Pageが表示されれば、Apacheは正常に起動しています。

デフォルトのWebルートは/var/www/html/です。そこにindex.htmlファイルを置くと、すぐに表示されます。これが基本です。

さて、本題に入りましょう。同じサーバーで2つ以上の異なるWebサイトをホストしたい場合はどうすればいいでしょうか?そこでバーチャルホストの出番です。

詳しく解説 — バーチャルホストを理解する

バーチャルホストとは?

バーチャルホストはApacheに指示します:「ドメインAへのリクエストが来たら、このフォルダのファイルを配信する。ドメインBなら、あちらのフォルダから配信する」と。

Apacheは2種類のバーチャルホストをサポートしています:

  • 名前ベースのバーチャルホスト — 複数のドメインが同じIPアドレスを共有する(最も一般的)
  • IPベースのバーチャルホスト — 各ドメインに固有のIPアドレスが割り当てられる(稀なケース、主にレガシーSSL構成で使用)

このガイドでは一貫して名前ベースのバーチャルホストを使用します。99%の構成で使われている方式です。

ApacheのConfigファイル構成

何かを変更する前に、UbuntuでApacheがどのようにconfigファイルを整理しているか理解しておきましょう:

/etc/apache2/
├── apache2.conf          # メインconfig
├── ports.conf            # Apacheがリッスンするポート
├── sites-available/      # すべてのバーチャルホストconfig(有効・無効問わず)
│   ├── 000-default.conf  # デフォルトサイトconfig
│   └── default-ssl.conf
├── sites-enabled/        # 有効なサイトへのシンボリックリンク
├── mods-available/       # 利用可能なApacheモジュール
└── mods-enabled/         # 有効なモジュールへのシンボリックリンク

重要なポイントはこれです:sites-available/にconfigを書いて、a2ensiteで有効化します。このコマンドがsites-enabled/にシンボリックリンクを作成します。Apacheはそこにシンボリックリンクされているものだけを読み込みます — それ以外は一切読みません。

最初のバーチャルホストをセットアップする

site1.comsite2.comの2つのサイトをホストする例で説明します。

ステップ1 — Webルートディレクトリの作成:

sudo mkdir -p /var/www/site1.com/public_html
sudo mkdir -p /var/www/site2.com/public_html

# 正しいオーナーを設定
sudo chown -R $USER:$USER /var/www/site1.com
sudo chown -R $USER:$USER /var/www/site2.com

# パーミッションを設定
sudo chmod -R 755 /var/www/site1.com
sudo chmod -R 755 /var/www/site2.com

ステップ2 — 各サイトにテストページを追加:

echo '<h1>サイト1へようこそ</h1>' | sudo tee /var/www/site1.com/public_html/index.html
echo '<h1>サイト2へようこそ</h1>' | sudo tee /var/www/site2.com/public_html/index.html

ステップ3 — バーチャルホストconfigファイルの作成:

sudo nano /etc/apache2/sites-available/site1.com.conf

以下を貼り付けてください:

<VirtualHost *:80>
    ServerName site1.com
    ServerAlias www.site1.com
    DocumentRoot /var/www/site1.com/public_html

    ErrorLog ${APACHE_LOG_DIR}/site1-error.log
    CustomLog ${APACHE_LOG_DIR}/site1-access.log combined

    <Directory /var/www/site1.com/public_html>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

site2の場合は、ファイルをコピーして一括置換します:

sudo cp /etc/apache2/sites-available/site1.com.conf /etc/apache2/sites-available/site2.com.conf
sudo sed -i 's/site1/site2/g' /etc/apache2/sites-available/site2.com.conf

ステップ4 — サイトを有効化してApacheをリロード:

sudo a2ensite site1.com.conf
sudo a2ensite site2.com.conf

# 必要に応じてデフォルトサイトを無効化
sudo a2dissite 000-default.conf

# リロード前にconfigをテスト — 必ず実行すること
sudo apache2ctl configtest

# Apacheをリロード
sudo systemctl reload apache2

configtestSyntax OKと表示されれば問題ありません。このステップを省略しないでください — 夜中の3時に何度も助けてもらったステップです。

応用 — HTTPS、.htaccess、マルチポート

Let’s Encrypt(Certbot)でHTTPSを有効化する

ローカルテストにはHTTPで十分ですが、本番環境ではHTTPSが必要です — そしてCertbotが最もクリーンな方法です:

sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache -d site1.com -d www.site1.com

Certbotはメールアドレスを尋ね、利用規約に同意すると、自動的にApache configを変更してSSLを追加してくれます。自動更新はsystemdタイマーで実行されます。証明書の期限切れを気にする必要がなくなります。

忘れる前に更新が正常に機能するか確認しておきましょう:

sudo certbot renew --dry-run

ディレクトリごとのルールに.htaccessを使用する

バーチャルホストconfigのAllowOverride All.htaccessファイルを有効化します。これにより、メインのApache configに触れることなく、フォルダごとにリライトルール、リダイレクト、アクセス制御を設定できます。

HTTPからHTTPSへのリダイレクトとwwwプレフィックスの削除が最も一般的な使用例です:

# /var/www/site1.com/public_html/.htaccess
RewriteEngine On

# wwwありからなしへリダイレクト
RewriteCond %{HTTP_HOST} ^www\.site1\.com [NC]
RewriteRule ^ https://site1.com%{REQUEST_URI} [L,R=301]

# HTTPからHTTPSへリダイレクト
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

mod_rewriteが有効になっていることを確認してください:

sudo a2enmod rewrite
sudo systemctl reload apache2

非標準ポートでバーチャルホストを実行する

別のサービスがポート80を使用している場合は、まずports.confにポート8080を追加します:

echo 'Listen 8080' | sudo tee -a /etc/apache2/ports.conf

次に、バーチャルホストconfigの*:80*:8080に変更します:

<VirtualHost *:8080>
    ServerName site1.com
    DocumentRoot /var/www/site1.com/public_html
    ...
</VirtualHost>

実践的なTips

バーチャルホストごとに別々のログファイルを設定する

各バーチャルホストに必ず個別のErrorLogCustomLogを定義してください。夜中の2時にsite2が壊れたとき、5つのサイトの出力が混在した1つのファイルをあさるのではなく、そのサイトのログを直接tailしたいですよね:

sudo tail -f /var/log/apache2/site2-error.log

Apacheが実際に使用しているConfigを確認する

# 有効なサイトを一覧表示
ls -la /etc/apache2/sites-enabled/

# コンパイル済みconfigを全表示
sudo apache2ctl -S

-Sフラグは、何かおかしいときに最初に使うオプションです。すべてのアクティブなバーチャルホスト、バインドするポート、ドキュメントルートを表示します。推測不要です。

私の環境からのパフォーマンスメモ

4GBのRAMを搭載したUbuntu 22.04サーバーで、PHP-FPMを有効化した後、prefork MPMからevent MPMに切り替えました。違いは明らかでした:preforkはワーカープロセスごとに約35MBを割り当て、メモリが枯渇する前に約60〜70の同時リクエストが上限でした。event MPM + PHP-FPMに切り替えた後、同じサーバーで200以上の同時接続を快適に処理できるようになりました — Apache自体はほぼステートレスになり、PHP-FPMが独自のワーカープールを別途管理します。

# preforkからevent MPMに切り替え
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo systemctl restart apache2

PHPを使用している場合は、これをPHP-FPMとproxy_fcgiモジュールと組み合わせてください。同じハードウェアでより多くの同時訪問者を処理できます。

クイックデバッグチェックリスト

バーチャルホストが機能しない場合は、順番にこのリストを確認してください:

  1. sudo apache2ctl configtestを実行する — 構文エラーがあるとすべて停止します
  2. sudo systemctl status apache2を確認する — 実際に起動しているか?
  3. DNSがサーバーのIPアドレスを指しているか確認する(/etc/hostsを編集してローカルでテストすることも可能)
  4. ドキュメントルートのファイルパーミッションを確認する — Apacheに読み取り権限が必要
  5. 汎用ログではなく、サイト固有のエラーログを確認する
  6. 必要なモジュールが有効になっているか確認する(ls /etc/apache2/mods-enabled/

Apacheのバーチャルホストは紙の上では複雑に見えます。一度セットアップすればシステム全体が理解できます。sites-availablesites-enabled間のシンボリックリンクパターン、a2ensite/a2dissiteのショートカット — 同じサーバーで2サイトを運営しても20サイトを運営してもクリーンにスケールします。

Share: