概要
Xserverで複数の(サブ)ドメインを運用していると、ドキュメントルート(例:public_html)直下に
- ルートドメイン(例:
https://example.tld/)のファイル - サブドメイン(例:
https://sub.example.tld/)のディレクトリ - 別サービス用のディレクトリ/シンボリックリンク
が混在しがち。
この混在状態のままだと、運用上は動いていても「管理がしづらい」「巻き込みが怖い」になりやすいので、ルートドメインの実体だけを1つの専用フォルダに隔離して、ルートとサブをフォルダで分けて整理する方法をメモしておく。
今回の方針は以下。
- 現状のサーバー構造(
public_html直下にサブドメインが並ぶなど)を変えない - ルートドメインの中身だけを
public_html/__root__/に集約 .htaccessを Host 条件付き Rewrite にして、サブドメインを巻き込まない
※ユーザー名・サーバー名・実ドメイン・実パスなどは、すべて <USER> / <SERVER> / example.tld / /home/<USER>/<DOMAIN>/public_html のダミー表記にしている。
前提環境
- レンタルサーバー:Apache +
.htaccessが利用できる環境(例:X系) - 対象:ルートドメイン(例:
https://example.tld/) - ドキュメントルート(例):
/home/<USER>/<DOMAIN>/public_html - 同一
public_html配下に、複数のサブドメイン(実体ディレクトリ/シンボリックリンク)が混在
1. ルートドメインの実体を1フォルダに集約する(実際にやった手順)
1-1. 事前バックアップ
まずは SSH ログインして、ルートドメインに関係するファイル/ディレクトリをバックアップしておく。ここでは例として __root_backup_YYYYMMDD を作って退避する。
ssh <USER>@<SERVER>
cd /home/<USER>/<DOMAIN>/public_html
# 念のためバックアップ(例:日付付き)
cp -a /home/<USER>/<DOMAIN>/public_html \
/home/<USER>/<DOMAIN>/__root_backup_$(date +%Y%m%d)
※本番環境だと「ディレクトリ丸ごとコピー」は容量を食うので、必要最低限の対象だけに絞っても良い。とにかく 戻せる状態 を作るのが大事。
1-2. ルートドメイン用の集約フォルダを作成
ルートドメインの実体を入れる専用フォルダを用意する(名前は何でも良いが、ここでは __root__ にする)。
cd /home/<USER>/<DOMAIN>/public_html
mkdir -p __root__
1-3. まずは「コピー」で配置(動作確認後に移動)
いきなり mv で移動すると怖いので、最初は cp -a で複製して動作確認 → OK なら最後に整理するのが安全。
cd /home/<USER>/<DOMAIN>/public_html
# 例:ルートドメインの実体(サイトの中身)を __root__ へコピー
# ※ 実際の対象は環境によって違うので、必要なものだけ選ぶ
cp -a \
index.html \
style.css \
img \
assets \
__root__/
※ .htaccess / .user.ini のような設定系は「影響範囲」があるので、まずは root 直下に残しつつ、必要に応じて __root__ 側にも配置、という段階運用が安全(後述)。
2. public_html/.htaccess を「振り分け専用」にする
ここが一番重要。混在しているサブドメインを巻き込まないために、Rewrite は必ず HTTP_HOST 条件付きにする。
Host 条件なしの Rewrite は危険。 同じ
public_htmlを参照している別サイトまで巻き込む可能性がある。
2-1. 旧パスのリダイレクトがある場合は「Host 条件付き」に寄せる
ルートドメイン側で「昔のパス互換」などを残している場合、Redirect permanent をそのまま置くと Host 条件で絞りにくい。混在環境では Rewrite に統一して Host 条件を付けた方が安心。
# 例:ルートドメインの時だけ old-path を new-subdomain へ 301
RewriteCond %{HTTP_HOST} ^(www\.)?example\.tld$ [NC]
RewriteRule ^old-path(/.*)?$ https://sub.example.tld$1 [R=301,L]
※上は “考え方” の例。実際のパスや転送先は環境に合わせて置き換える。
2-2. ルートドメインだけ __root__ に内部転送する(完成形)
public_html/.htaccess は「振り分け役」に徹し、ルートドメイン(example.tld / www.example.tld)のアクセスだけ __root__ を参照させる。
# (必要なら)サーバー側キャッシュ制御の環境変数は残す
SetEnvIf Request_URI ".*" Ngx_Cache_NoCacheMode=off
SetEnvIf Request_URI ".*" Ngx_Cache_AllCacheMode
<IfModule mod_rewrite.c>
RewriteEngine On
# ------------------------------------
# (A) __root__ への直アクセスを拒否(内部Rewriteは許可)
# ------------------------------------
RewriteCond %{THE_REQUEST} \s/+__root__/ [NC]
RewriteRule ^__root__/ - [F,L]
# ------------------------------------
# (B) ルートドメイン(example.tld / www.example.tld)のみ __root__ に内部転送
# ------------------------------------
RewriteCond %{HTTP_HOST} ^(www\.)?example\.tld$ [NC]
RewriteCond %{REQUEST_URI} !^/\.well-known/ [NC]
RewriteCond %{REQUEST_URI} !^/__root__/ [NC]
RewriteRule ^(.*)$ /__root__/$1 [L]
</IfModule>
ポイント:
HTTP_HOST条件があるので、sub.example.tld等は巻き込まれない/.well-known/を除外しておくと SSL 更新まわりで詰まりにくい__root__の直アクセスを拒否しておくと、URLとして露出しない
3. 動作確認(必須)
確認観点は以下。
- ルートドメイン(
https://example.tld/)が__root__の内容を表示する - サブドメイン(例:
https://sub.example.tld/)に影響が出ない __root__が外部URLとして露出しない(直アクセスが拒否される)
サーバー上で curl が使えるなら、ヘッダ確認が簡単。
# ルートドメイン(200 になるか)
curl -I https://example.tld/
# __root__ 直アクセス(403 になる想定)
curl -I https://example.tld/__root__/
※ curl が使えない場合は、ブラウザで
https://example.tld/(表示OK)https://example.tld/__root__/(拒否される)
の2つを確認するだけでも良い。
4. 最後に整理(コピー→動作OKの後)
動作確認が取れたら、ルート直下に残っている「サイト実体」を __root__ 側へ mv して、ルート直下は “ハブ” として薄くする。
# 例:サイト実体を移動(環境に合わせて)
cd /home/<USER>/<DOMAIN>/public_html
mv img __root__/
mv assets __root__/
mv index.html __root__/
mv style.css __root__/
public_html 直下に残るのは基本的に
.htaccess(振り分け専用)__root__(ルートドメイン実体)- サブドメインのディレクトリ/リンク(既存のまま)
という状態になり、ルートとサブの責務が分離できる。
5. 公開時に気をつけるポイント(自分用メモ)
- 実ドメイン・実サーバー名・実ユーザー名・実パスはダミー化
- Rewrite は必ず
HTTP_HOST条件で絞る(巻き込み防止) .user.iniは影響範囲があるため、いきなり移動せず段階的に/.well-known/の除外を入れておく(SSL更新系)
以上、public_html 直下に混在している環境でも、ルートドメインの実体を __root__ に隔離して、ルートとサブをフォルダで分けて整理する方法のメモ。

コメント