2026年8月9日
2026年8月9日
Apacheでサブドメインを設定する方法(DNS・バーチャルホスト・HTTPS)
Apacheでサブドメイン(blog.example.com や shop.example.com など)を動かすには、DNSにサブドメインのレコードを追加し、Apacheにそのサブドメイン専用のバーチャルホストを作る、という2つの作業が必要です。この記事では、DNSの設定、Ubuntu・RHEL系それぞれでのバーチャルホストの書き方、HTTPS化(個別証明書とワイルドカード証明書の違い)、サブドメインにWordPressを置くときの注意点、表示されないときの確認順までを説明します。
バーチャルホストそのものの基本(ServerName の振り分けの仕組みや、一致しないリクエストの受け皿)は別記事で扱っているので、ここではサブドメイン特有の部分に絞ります。
全体の流れ
サブドメインの追加は、次の順に進めると迷いにくくなります。
- DNSにサブドメインのレコードを追加する
- 公開ディレクトリを作る
- サブドメイン用のバーチャルホストを作り、文法を確認して再読み込みする
- HTTPで表示を確認してから、証明書を取得してHTTPS化する
DNSとApacheは独立しているので、どちらか片方だけでは表示されません。DNSは反映に時間がかかることがあるため、最初に追加しておき、待っている間にApache側を準備するのが効率的です。
DNSにレコードを追加する
ドメインを管理しているDNSサービス(レジストラやCloudflareなど)の管理画面で、サブドメインのレコードを追加します。
- Aレコード:
blogという名前で、サーバーのIPv4アドレスを指定します。IPv6で待ち受けているならAAAAレコードも追加します。 - CNAMEレコード: 同じサーバーに向けるだけなら、
blogをexample.comの別名にする方法もあります。親ドメインのIPアドレスを変えたときに追随するので、管理は楽になります。
追加したら、サーバー以外の場所から名前解決できるかを確かめます。
dig +short blog.example.com A
dig +short blog.example.com @8.8.8.8
サーバーのIPアドレスが返れば準備完了です。何も返らない場合は、レコード名の入力ミス(blog.example.com.example.com のように二重になっている)や、ドメインのネームサーバーが別のサービスを向いていないかを確認します。以前に存在しないと問い合わせた結果がキャッシュされていると、反映が遅れて見えることもあります。
公開ディレクトリを作る
サブドメインごとにディレクトリを分けると、権限やログを切り分けやすくなります。
sudo mkdir -p /var/www/blog.example.com/public
echo 'blog.example.com OK' | sudo tee /var/www/blog.example.com/public/index.html
親ドメインのディレクトリの中(/var/www/example.com/public/blog など)をサブドメインの公開先にすることもできますが、同じファイルが example.com/blog/ と blog.example.com の両方から見えてしまいます。重複したURLが生まれるうえ、片方のサイトの .htaccess がもう片方に影響することもあるため、別ディレクトリにしておくのが無難です。
バーチャルホストを作る(Ubuntu)
Ubuntuでは /etc/apache2/sites-available/ に設定ファイルを置き、a2ensite で有効にします。
# /etc/apache2/sites-available/blog.example.com.conf
<VirtualHost *:80>
ServerName blog.example.com
DocumentRoot /var/www/blog.example.com/public
<Directory /var/www/blog.example.com/public>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/blog.example.com-error.log
CustomLog ${APACHE_LOG_DIR}/blog.example.com-access.log combined
</VirtualHost>
sudo a2ensite blog.example.com.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
バーチャルホストを作る(RHEL系)
AlmaLinuxやRocky Linuxなどでは、/etc/httpd/conf.d/ に .conf で終わるファイルを置くと読み込まれます。中身は上と同じで、ログの場所だけ /var/log/httpd/ に変えます。
sudo apachectl configtest
sudo systemctl reload httpd
公開ディレクトリを /var/www の外に作った場合は、SELinuxのラベル(httpd_sys_content_t)を付けないと403になります。
設定が正しく認識されているか確かめる
configtest で Syntax OK が出ても、意図どおりに振り分けられているとは限りません。次のコマンドで、Apacheがどのサブドメインをどのファイルで定義しているかを一覧できます。
sudo apachectl -S
blog.example.com が表示されていれば、Apacheは認識しています。DNSの反映を待たずにApache側だけ確認したい場合は、サーバーのIPアドレスに Host ヘッダーを付けてリクエストします。
curl -I -H "Host: blog.example.com" http://203.0.113.10/
ここで index.html の内容ではなく親ドメインのサイトが返ってくる場合は、サブドメインのバーチャルホストが読み込まれておらず、一致しないリクエストとして最初のバーチャルホストに回されています。
ワイルドカードでまとめて受ける場合
サブドメインを利用者ごとに自動で増やす仕組み(WordPressマルチサイトのサブドメイン型など)では、1つずつバーチャルホストを書くのは現実的ではありません。その場合は、DNSにワイルドカードレコード(* のAレコード)を作り、Apacheでは ServerAlias にワイルドカードを書きます。
<VirtualHost *:80>
ServerName example.com
ServerAlias *.example.com
DocumentRoot /var/www/example.com/public
# Directory設定は通常のサイトと同じ
</VirtualHost>
個別に定義したサブドメイン(blog.example.com など)とワイルドカードが同じポートに並んでいる場合、Apacheは設定を読み込んだ順に照合し、最初に一致したものを使います。個別のサブドメインのファイルが、ワイルドカードを書いたファイルより先に読み込まれるようにしてください。Ubuntuでは sites-enabled 内のファイル名の順、RHEL系では conf.d 内のファイル名の順で読み込まれます。apachectl -S で並び順を確認できます。
HTTPS化する
サブドメインはそれぞれ別のホスト名なので、親ドメインの証明書がそのまま使えるとは限りません。
- サブドメインごとに証明書を取る: Let's Encryptを使うなら、
sudo certbot --apache -d blog.example.comのように指定すると、HTTP経由の認証で取得でき、443番用の設定も作られます。親ドメインと同じ証明書に含めたい場合は-d example.com -d www.example.com -d blog.example.comのように並べます。 - ワイルドカード証明書を使う:
*.example.comの証明書は、Let's EncryptではDNS経由の認証(DNS-01)でしか取得できません。DNSサービスに対応したCertbotのプラグインを使うと、更新も自動化しやすくなります。
ワイルドカード証明書が有効なのは1階層だけです。*.example.com は blog.example.com には使えますが、dev.blog.example.com や、親の example.com そのものには使えません。親ドメインも同じ証明書で扱いたい場合は、example.com と *.example.com の両方を含めて発行します。
Certbotのプラグインの名前や対応しているDNSサービスは変わることがあるため、使う前にCertbotの公式ドキュメントで確認してください(2026年10月現在)。
サブドメインにWordPressを置くときの注意
サブドメインに独立したWordPressを置く場合は、通常のインストールと同じ手順で問題ありませんが、いくつか気をつけたい点があります。
- データベースを分ける: 親ドメインのWordPressと同じデータベースを使う場合は、テーブル接頭辞(
$table_prefix)を変えます。分けておくほうがバックアップや移行が楽です。 - サイトアドレス: インストール時のURLを
https://blog.example.comにしておきます。後からHTTPS化する場合は、作業前にデータベースのバックアップを取ってから「設定」→「一般」のアドレスを変更します。 - Cookieの範囲: WordPressのログインCookieは標準ではそのホスト名だけに発行されます。
wp-config.phpでCOOKIE_DOMAINを親ドメインに広げると、サブドメイン間でCookieが共有されるため、意図がない限り設定しないでください。 - マルチサイトのサブドメイン型: 子サイトがサブドメインになるマルチサイトでは、前述のワイルドカードのDNS・
ServerAlias・証明書がそろっている必要があります。マルチサイトへの変更は影響が大きいので、ステージング環境で試してから本番に適用します。
表示されないときの確認順
- ブラウザで「サーバーが見つかりません」となる: DNSの問題です。
digで名前解決できるか、別のDNSサーバーでも同じ結果かを確認します。 - 親ドメインのサイトや初期ページが表示される: Apacheがサブドメインのバーチャルホストを認識していません。
apachectl -Sに表示されるか、a2ensiteを実行したか、再読み込みしたかを確認します。 - 403 Forbidden: エラーログで
client denied by server configurationならRequire all grantedの不足、Permission deniedならディレクトリの権限、RHEL系ならSELinuxのラベルを確認します。 - HTTPSで証明書の警告が出る: 証明書にそのサブドメイン名が含まれていません。
openssl s_client -connect blog.example.com:443 -servername blog.example.comで、返ってくる証明書の名前を確認します。
まとめ
- サブドメインの追加は、DNSのレコード追加とApacheのバーチャルホスト作成の2つがそろって初めて動きます。
- バーチャルホストはサブドメインごとに別ファイル・別ディレクトリにすると、権限やログの切り分けが楽です。
apachectl -SとHostヘッダー付きのcurlで、DNSの反映前でもApache側の設定を確かめられます。- ワイルドカードの
ServerAliasを使う場合は、個別のサブドメインが先に読み込まれる順にします。 - ワイルドカード証明書はDNS-01認証が必要で、有効なのは1階層だけです。