Apache設定を「プログラミング」する:mod_macro「Use」とテンプレート活用の具体例
mod_macro
は、Apache HTTP Serverの設定ファイル内でマクロを定義し、それを使用するためのモジュールです。これにより、繰り返し登場する設定ブロックをテンプレート化し、より簡潔で管理しやすい設定ファイルを作成できます。
「Use」ディレクティブは、定義済みのマクロを呼び出して展開するために使用されます。
どのような時に役立つか?
例えば、複数のバーチャルホスト(Virtual Host)がほぼ同じ設定を持っている場合を考えてみてください。それぞれのバーチャルホストに対して、DocumentRoot
、ErrorLog
、CustomLog
などのディレクティブを毎回記述するのは手間がかかり、ミスも発生しやすくなります。
mod_macro
を使えば、これらの共通する設定をマクロとして一度定義し、Use
ディレクティブを使って必要な箇所でそのマクロを呼び出すことができます。
Use
ディレクティブの構文と動作
Use
ディレクティブの基本的な構文は以下の通りです。
Use name [value1 valueN]
[value1 valueN]
: マクロの定義で指定されたパラメーターに対応する値を指定します。マクロ定義で指定されたパラメーターの数と、Use
で渡す引数の数は一致させる必要があります。name
: 呼び出すマクロの名前を指定します。この名前は、<Macro>
ディレクティブで定義されたものと一致する必要があります。
Use
ディレクティブが実行されると、以下の処理が行われます。
- 指定されたマクロ(
name
)が検索されます。 Use
ディレクティブで渡された値(value1
など)が、マクロ定義で対応するパラメーターに置き換えられます。- 展開された設定ブロックが、あたかもそこに直接記述されたかのようにApacheによって処理されます。
具体例
バーチャルホストを定義するマクロの例を見てみましょう。
まず、<Macro>
ディレクティブを使ってマクロを定義します。
<Macro VHost $name $domain $docroot>
<VirtualHost *:80>
ServerName $domain
ServerAlias www.$domain
DocumentRoot "/var/www/vhosts/$docroot"
ErrorLog "/var/log/httpd/$name.error_log"
CustomLog "/var/log/httpd/$name.access_log" combined
</VirtualHost>
</Macro>
このマクロはVHost
という名前で、$name
、$domain
、$docroot
という3つのパラメーターを受け取ります。
次に、このマクロをUse
ディレクティブで呼び出します。
Use VHost example example.com example_site
Use VHost myapp myapp.net myapp_site
上記のUse
ディレクティブは、Apacheの起動時に以下のように展開されて処理されます。
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot "/var/www/vhosts/example_site"
ErrorLog "/var/log/httpd/example.error_log"
CustomLog "/var/log/httpd/example.access_log" combined
</VirtualHost>
<VirtualHost *:80>
ServerName myapp.net
ServerAlias www.myapp.net
DocumentRoot "/var/www/vhosts/myapp_site"
ErrorLog "/var/log/httpd/myapp.error_log"
CustomLog "/var/log/httpd/myapp.access_log" combined
</VirtualHost>
このように、Use
ディレクティブを使うことで、複数の類似した設定ブロックを簡潔に記述し、設定ファイルの可読性と保守性を高めることができます。
注意点
- 展開はApache起動時: マクロはApacheの起動時に展開されます。動的にマクロの内容が変化するわけではありません。
- 再帰の検出: マクロの展開が無限ループにならないように、
mod_macro
は再帰的なマクロ展開を検出してエラーを出力します。 - パラメーターの命名規則: パラメーター名には、他のディレクティブとの衝突を避けるために
$
、%
、@
などのプレフィックスを付けるのが推奨されます。 - 引数の数の一致:
Use
で渡す引数の数は、マクロ定義のパラメーターの数と完全に一致させる必要があります。
mod_macro
はApacheの設定を簡潔にする強力なツールですが、その性質上、設定ミスが発生しやすい部分でもあります。特にUse
ディレクティブはマクロの展開を担うため、エラーの原因となることがよくあります。
マクロが定義されていない、またはUseの前に定義されていない
エラー例
[macro:error] Use of undefined macro 'MyVHost'
原因
Use
ディレクティブで呼び出そうとしているマクロ(この例ではMyVHost
)が、Apacheの設定ファイル内で<Macro>
ディレクティブによって定義されていないか、Use
ディレクティブより後の行で定義されている場合に発生します。Apacheは設定ファイルを上から順に読み込むため、マクロはUse
される前に定義されている必要があります。
トラブルシューティング
- マクロ定義の確認
httpd.conf
やインクルードされている設定ファイル内で、Use
しているマクロ名と一致する<Macro>
ディレクティブが正しく記述されているかを確認します。
引数の数がマクロ定義と一致しない
エラー例
[macro:error] Macro 'MyMacro' invoked with 2 arguments, but defined with 3 arguments.
原因
Use
ディレクティブで渡す引数の数(パラメーターの数)が、<Macro>
ディレクティブで定義されたパラメーターの数と異なる場合に発生します。
トラブルシューティング
-
Useディレクティブの確認
Use
ディレクティブで、マクロ定義で指定された数と同じ数の引数が渡されているかを確認します。例:
# マクロ定義 (3つの引数) <Macro MyVHost $domain $docroot $logname> ServerName $domain DocumentRoot "/var/www/$docroot" ErrorLog "/var/log/httpd/$logname.error_log" </Macro> # 正しいUse (3つの引数) Use MyVHost example.com public_html example # 誤ったUse (2つの引数) -> エラー Use MyVHost example.com public_html
-
マクロ定義の確認
<Macro>
ディレクティブを見て、いくつのパラメーター($param1 $param2
など)が定義されているかを確認します。
パラメーター名の衝突、または意図しない置換
警告例
[macro:warn] Parameter '$name' in macro 'MyMacro' is shadowed by a global define.
(または類似の警告)
原因
mod_macro
のパラメーター名が、Apacheの他のディレクティブ(例: Define
)や他のマクロのパラメーター名と衝突している場合に発生する可能性があります。また、mod_macro
はテキスト置換を行うため、意図しない文字列が置換されてしまい、結果的に設定エラーになることもあります。
トラブルシューティング
- UndefMacroの使用
マクロの使用が終わったら、UndefMacro
ディレクティブを使ってマクロの定義を解除することを検討します。これにより、大規模な設定ファイルで変数名の衝突を避けるのに役立ちます。 - パラメーター名のプレフィックス
パラメーター名には、$
、%
、@
などのシグナル(記号)を付けることが強く推奨されます。これにより、一般的なディレクティブ名との衝突を避けることができます。公式ドキュメントでも推奨されています。 例:$name
ではなく${name}
のようにブレースで囲むことで、より明確な置換範囲を指定できます。
マクロ内で許可されないディレクティブの使用
エラー例
[core:crit] [pid 12345:tid 67890] (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
(直接的なmod_macro
のエラーメッセージではないが、マクロ展開の結果として発生)
原因
mod_macro
自体はディレクティブの構文を深くチェックするわけではありません。マクロが展開された結果として、Apacheが認識できないディレクティブや、コンテキスト(server config
、VirtualHost
、Directory
など)が正しくないディレクティブが含まれてしまうと、Apacheの構文チェックでエラーが発生します。例えば、<Macro>
内でListen
ディレクティブを定義し、それを複数回Use
すると、同じポートを複数回リッスンしようとして「Address already in use」のようなエラーが出ることがあります。
トラブルシューティング
- マクロの出力確認 (デバッグ)
複雑なマクロの場合、実際にどのように展開されているかを確認するのが難しいことがあります。一時的にマクロ内の内容をコメントアウトし、手動で展開後の内容を直接設定ファイルに記述してみて、それが動作するかどうかをテストする方法も有効です。 - エラーログの確認
Apacheのエラーログ(通常、/var/log/httpd/error_log
や/var/log/apache2/error.log
)を確認します。マクロ展開後の最終的な設定に問題がある場合、ここに詳細なエラーメッセージが出力されます。
mod_macroモジュールがロードされていない
エラー例
[core:error] Invalid command 'Macro', perhaps misspelled or defined by a module not included in the server configuration
[core:error] Invalid command 'Use', perhaps misspelled or defined by a module not included in the server configuration
原因
mod_macro
を使用するためには、Apacheの設定でこのモジュールがロードされている必要があります。
トラブルシューティング
- モジュールファイルの存在確認
modules/mod_macro.so
ファイルがApacheのモジュールディレクトリに実際に存在するかを確認します。 - モジュールのロード確認
httpd.conf
または対応するconf.d/
内のファイルで、LoadModule macro_module modules/mod_macro.so
という行がコメントアウトされておらず、正しく記述されているかを確認します。
全体的なトラブルシューティングのヒント
- 公式ドキュメントの参照
mod_macro
の公式ドキュメント(Apache HTTP Server Version 2.4 - mod_macro)は、最も正確で詳細な情報源です。 - 小さなステップで変更
複雑なマクロを作成する際は、少しずつ変更を加えてはテストする(configtest
とリロード/再起動)ことを繰り返すのが効果的です。 - Apacheエラーログの確認
ほとんどの問題はエラーログに詳細な情報が出力されます。エラーログのパスはhttpd.conf
のErrorLog
ディレクティブで確認できます。 - apachectl configtestの活用
これが最も基本的なツールです。設定変更後は常に実行し、エラーメッセージを注意深く読みましょう。
mod_macro
は、Apacheの設定ファイル内で繰り返し現れるパターンを抽象化し、再利用可能にするためのモジュールです。特に、複数の仮想ホスト(Virtual Host)やディレクトリに似た設定を適用する場合に非常に便利です。
ここでは、いくつかの一般的なシナリオにおけるUse
ディレクティブの使用例を示します。
例1: 複数の仮想ホストを簡潔に定義する
最も一般的なmod_macro
のユースケースです。Webサイトごとに類似した設定(ドキュメントルート、ログファイルなど)を持つ場合に役立ちます。
マクロ定義 (/etc/httpd/conf.d/vhosts_macro.conf
など):
# mod_macro モジュールがロードされていることを確認
# LoadModule macro_module modules/mod_macro.so
# VHost マクロの定義
# $name: サイトの識別名 (ログファイル名などに使用)
# $domain: ドメイン名 (ServerName, ServerAlias に使用)
# $docroot: ドキュメントルートのパス
<Macro VHost $name $domain $docroot>
<VirtualHost *:80>
ServerName $domain
ServerAlias www.$domain
# ドキュメントルートのパス
DocumentRoot "/var/www/html/$docroot"
# エラーログとアクセスログ
ErrorLog "/var/log/httpd/$name.error_log"
CustomLog "/var/log/httpd/$name.access_log" combined
# ディレクトリ設定 (例: AllowOverride All)
<Directory "/var/www/html/$docroot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
# HTTPS (ポート443) の場合も同様に定義することが多い
<VirtualHost *:443>
ServerName $domain
ServerAlias www.$domain
DocumentRoot "/var/www/html/$docroot"
ErrorLog "/var/log/httpd/$name.ssl_error_log"
CustomLog "/var/log/httpd/$name.ssl_access_log" combined
# SSL/TLS 設定 (実際にはもっと多くの設定が必要)
SSLEngine on
SSLCertificateFile "/etc/pki/tls/certs/$name.crt"
SSLCertificateKeyFile "/etc/pki/tls/private/$name.key"
<Directory "/var/www/html/$docroot">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
</Macro>
マクロの使用 (httpd.conf
または別の設定ファイル):
# マクロ定義ファイルをインクルード (必要に応じて)
IncludeOptional conf.d/vhosts_macro.conf
# サイトA の設定
# Use VHost [name] [domain] [docroot]
Use VHost example_site example.com example_site_root
# サイトB の設定
Use VHost blog_site blog.example.org blog_root
# サイトC の設定
Use VHost project_app app.example.net project_app_root
解説
Use
ディレクティブは、<Macro VHost ...>
で定義されたマクロを呼び出します。各Use
行で指定された3つの引数(example_site
, example.com
, example_site_root
など)が、マクロ内の$name
, $domain
, $docroot
にそれぞれ置換され、展開された<VirtualHost>
ブロックがApacheによって処理されます。これにより、新しいサイトを追加する際に、Use
ディレクティブを1行追加するだけで済むようになります。
例2: 特定のディレクトリに対する共通のアクセス制限を適用する
複数の管理用ディレクトリやプライベートなコンテンツディレクトリに同じ認証やアクセス制限を適用する場合に便利です。
マクロ定義 (/etc/httpd/conf.d/access_macro.conf
など):
# ProtectedDir マクロの定義
# $path: 保護対象のディレクトリパス
# $group: アクセスを許可するグループ名
<Macro ProtectedDir $path $group>
<Directory "$path">
AuthType Basic
AuthName "Restricted Area"
AuthUserFile "/etc/httpd/conf.d/.htpasswd"
Require group $group
</Directory>
</Macro>
# IPアドレスで制限するマクロの定義
# $path: 制限対象のディレクトリパス
# $ip_address: 許可するIPアドレスまたはCIDR
<Macro RestrictByIP $path $ip_address>
<Directory "$path">
Order deny,allow
Deny from all
Allow from $ip_address
</Directory>
</Macro>
マクロの使用 (httpd.conf
または別の設定ファイル):
IncludeOptional conf.d/access_macro.conf
# 管理者のみがアクセスできるディレクトリ
Use ProtectedDir "/var/www/html/admin" admin_users
# 開発者のみがアクセスできるディレクトリ
Use ProtectedDir "/var/www/html/dev" dev_users
# 特定のIPアドレスからのみアクセスできるディレクトリ
Use RestrictByIP "/var/www/html/private" "192.168.1.0/24"
# 複数のIPアドレスを許可する場合(引用符で囲む)
Use RestrictByIP "/var/www/html/public_api" "10.0.0.0/8 172.16.0.0/16"
解説
ProtectedDir
マクロは、指定されたディレクトリに対して基本的な認証を適用します。RestrictByIP
マクロは、特定のIPアドレス範囲からのアクセスのみを許可します。このように、共通のセキュリティポリシーをマクロ化し、複数の場所に簡単に適用できます。
例3: RewriteRule の共通パターンを抽象化する
Apacheのmod_rewrite
は非常に強力ですが、複雑なルールは記述が冗長になりがちです。共通のRewriteルールパターンをマクロ化することで、可読性を向上させることができます。
マクロ定義 (/etc/httpd/conf.d/rewrite_macro.conf
など):
# HTTP から HTTPS へのリダイレクトを強制するマクロ
# $domain: 強制するドメイン名
<Macro ForceHTTPS $domain>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(?:www\.)?$domain$ [NC]
RewriteRule ^(.*)$ https://$domain$1 [R=301,L]
</Macro>
# 特定の旧URLから新URLへのリダイレクトマクロ
# $old_path: 旧パス
# $new_path: 新パス
<Macro RedirectOldURL $old_path $new_path>
RewriteEngine On
RewriteRule ^$old_path/?$ $new_path [R=301,L]
</Macro>
マクロの使用 (VirtualHost
内、またはhttpd.conf
の適切な場所):
IncludeOptional conf.d/rewrite_macro.conf
<VirtualHost *:80>
ServerName myapp.com
ServerAlias www.myapp.com
DocumentRoot "/var/www/html/myapp"
# このサイトでHTTPSを強制
Use ForceHTTPS myapp.com
# 古いブログ記事のURLを新しいURLにリダイレクト
Use RedirectOldURL /old-blog-post /new-article
Use RedirectOldURL /legacy-page /modern-content
</VirtualHost>
解説
ForceHTTPS
マクロは、HTTPリクエストをHTTPSに自動的にリダイレクトする一般的なパターンをカプセル化します。RedirectOldURL
マクロは、サイトのリニューアルなどで多数の旧URLを新URLにリダイレクトする必要がある場合に、ルールを簡潔に記述できます。
重要なヒント
- デバッグ: マクロが期待通りに動作しない場合は、
apachectl configtest
を実行して構文エラーがないか確認し、Apacheのエラーログを詳しくチェックしてください。場合によっては、マクロ内の内容を一時的に直接記述してテストし、展開後の形を確認するのも有効です。 - パラメーターの命名: パラメーター名(例:
$name
)は、他の設定ディレクティブとの衝突を避けるために、$
、%
、@
などの記号を先頭に付けることが推奨されます。また、${name}
のようにブレースで囲むことで、置換の範囲を明確にできます。 - 定義と使用の順序: マクロは、
Use
されるよりも前に定義されている必要があります。通常は、専用のマクロ定義ファイルをInclude
ディレクティブで設定ファイルの冒頭に近い場所で読み込むのが良いプラクティスです。 - モジュールのロード:
mod_macro
を使用する前に、LoadModule macro_module modules/mod_macro.so
がApacheの設定ファイルで有効になっていることを確認してください。
mod_macro
はApache内部でのマクロ展開を行いますが、より柔軟な設定管理や自動化を目指す場合、外部ツールや他のApache機能と組み合わせる方法が一般的です。
Include ディレクティブと変数 (Define) の組み合わせ
mod_macro
と似たアプローチですが、よりシンプルなケースで利用できます。Apache 2.4以降で導入されたDefine
ディレクティブを使うことで、設定ファイル内で変数を定義し、それをInclude
するファイル内で利用できます。
特徴
- 適用範囲
グローバルな設定や、VirtualHost
、Directory
などのブロック全体をインクルードするのに適しています。 - 柔軟性
Include
するファイルの内容は完全に静的であるため、複雑な条件分岐などには向いていません。 - シンプルさ
mod_macro
のようなマクロ構文を学習する必要がなく、より直感的に利用できます。
コード例
httpd.conf またはメインの設定ファイル
# 変数の定義
Define DOCROOT_BASE "/var/www/html"
Define LOG_BASE "/var/log/httpd"
# サイトAの設定をインクルード
Define SITENAME "example_site"
Define DOMAIN "example.com"
Define SITE_DIR "example_root"
IncludeOptional conf.d/vhost_template.conf
# サイトBの設定をインクルード
Define SITENAME "blog_site"
Define DOMAIN "blog.example.org"
Define SITE_DIR "blog_root"
IncludeOptional conf.d/vhost_template.conf
conf.d/vhost_template.conf (テンプレートファイル)
<VirtualHost *:80>
ServerName ${DOMAIN}
ServerAlias www.${DOMAIN}
DocumentRoot "${DOCROOT_BASE}/${SITE_DIR}"
ErrorLog "${LOG_BASE}/${SITENAME}.error_log"
CustomLog "${LOG_BASE}/${SITENAME}.access_log" combined
<Directory "${DOCROOT_BASE}/${SITE_DIR}">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
解説
Define
で変数を定義し、IncludeOptional
でテンプレートファイルを読み込みます。テンプレートファイル内では${VARIABLE_NAME}
形式で変数を使用します。これはmod_macro
が導入される前から存在した概念で、Apacheの基本的な機能の一部です。
動的な仮想ホスト (mod_vhost_alias)
多数の類似した仮想ホストを、個別に設定ファイルを作成せずに動的に生成したい場合に非常に強力です。
特徴
- 制限
設定の柔軟性はmod_macro
やテンプレートエンジンに比べて低く、全てのディレクティブを動的にすることはできません。 - 自動化
ドキュメントルートやログファイルのパスをドメイン名に基づいて自動的に決定できます。 - 大規模環境向け
数十、数百といった仮想ホストを管理するのに適しています。
コード例
# mod_vhost_alias モジュールがロードされていることを確認
# LoadModule vhost_alias_module modules/mod_vhost_alias.so
# ドキュメントルートのベースディレクトリ
# 例えば、example.com は /var/www/vhosts/example.com にマッピング
VirtualDocumentRoot "/var/www/vhosts/%0"
VirtualDocumentRootUserDir disabled
# エラーログとアクセスログもドメイン名に基づいて生成
ErrorLog "/var/log/httpd/%0.error_log"
CustomLog "/var/log/httpd/%0.access_log" combined
<Directory "/var/www/vhosts/*">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
解説
VirtualDocumentRoot %0
は、リクエストされたホスト名全体(例: www.example.com
)をドキュメントルートのパスに利用します。これにより、/var/www/vhosts/www.example.com
といったディレクトリを自動的に参照するようになります。%0
以外にも、ドメインの各部分(%1
, %2
など)を使用することも可能です。
外部のテンプレートエンジン / 設定管理ツール
最も柔軟で、大規模なインフラストラクチャやCI/CDパイプラインで利用される方法です。Apacheの設定ファイル自体をテンプレートとして扱い、RubyのERB、PythonのJinja2、Goのtext/templateなど、汎用的なテンプレートエンジンを用いて生成します。
ツール例
- 専用のスクリプト
PythonやPerlなどのスクリプト言語で、独自のロジックに基づいて設定ファイルを生成するスクリプトを作成します。 - Make, Bashスクリプト
シンプルなケースでは、sed
やawk
、envsubst
などのコマンドラインツールとシェルスクリプトを組み合わせて設定ファイルを生成することも可能です。 - Ansible, Puppet, Chef, SaltStack
これらは構成管理ツールであり、Apacheの設定ファイルをテンプレートとして管理し、複数のサーバーにデプロイするのに最適です。
特徴
- 複雑性の増加
外部ツールを導入する学習コストや、ツールの管理・運用が必要になります。 - バージョン管理
テンプレート自体をバージョン管理システムで管理することで、設定の変更履歴を追跡しやすくなります。 - 集中管理
一元化されたテンプレートとデータから複数のサーバーの設定を生成・デプロイできます。 - 最大限の柔軟性
プログラミング言語の全ての機能(条件分岐、ループ、外部データソースからの取得など)を組み合わせて設定を生成できます。
コード例 (Ansible + Jinja2 テンプレートの概念)
templates/httpd.conf.j2 (Jinja2 テンプレートファイル)
# This is the main Apache HTTP server configuration file
# Managed by Ansible - DO NOT EDIT MANUALLY
ServerRoot "/etc/httpd"
Listen {{ apache_http_port }}
Include conf.modules.d/*.conf
User {{ apache_user }}
Group {{ apache_group }}
# ... 他のグローバル設定 ...
{% for site in sites %}
<VirtualHost *:{{ apache_http_port }}>
ServerName {{ site.domain }}
ServerAlias www.{{ site.domain }}
DocumentRoot "{{ apache_docroot_base }}/{{ site.docroot_dir }}"
ErrorLog "{{ apache_log_base }}/{{ site.name }}.error_log"
CustomLog "{{ apache_log_base }}/{{ site.name }}.access_log" combined
<Directory "{{ apache_docroot_base }}/{{ site.docroot_dir }}">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
{% if site.ssl_enabled %}
# HTTPS 設定 (簡易版)
SSLEngine on
SSLCertificateFile "/etc/pki/tls/certs/{{ site.name }}.crt"
SSLCertificateKeyFile "/etc/pki/tls/private/{{ site.name }}.key"
{% endif %}
</VirtualHost>
{% endfor %}
vars/main.yml (Ansible 変数ファイル)
apache_http_port: 80
apache_user: apache
apache_group: apache
apache_docroot_base: /var/www/html
apache_log_base: /var/log/httpd
sites:
- name: example_site
domain: example.com
docroot_dir: example_site_root
ssl_enabled: true
- name: blog_site
domain: blog.example.org
docroot_dir: blog_root
ssl_enabled: false
- name: project_app
domain: app.example.net
docroot_dir: project_app_root
ssl_enabled: true
解説
Ansibleがvars/main.yml
で定義されたsites
リストをループ処理し、httpd.conf.j2
テンプレートをレンダリングして最終的なhttpd.conf
ファイルを生成します。これにより、Apacheの設定ファイル自体は静的なファイルでありながら、その内容は外部のデータとロジックによって動的に生成されるため、非常に柔軟な管理が可能になります。
代替方法 | 利点 | 欠点 |
---|---|---|
Include + Define | mod_macro よりシンプル、Apache標準機能 | 条件分岐や繰り返しができない、設定項目が多いと冗長になりやすい |
mod_vhost_alias | 多数の仮想ホストの動的な自動生成、手動設定の削減 | 設定の柔軟性が低い、特定のパターンにしか適用できない |
外部のテンプレートエンジン | 最大限の柔軟性、プログラミングロジックの適用、一元的な設定管理、バージョン管理との親和性 | 外部ツールの学習と運用コスト、Apache起動前にファイル生成が必要 |