読者です 読者をやめる 読者になる 読者になる

北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

Apache2を1台のマシンで複数インスタンス起動するメモ

perl+web

1台のマシンにApache2を複数インスタンス建てたくなった*1んで、調べたことをメモっときます。

先に結論

Apache2の複数起動は結構泥臭いです。httpdに「-f your-httpd.conf」オプションを渡すために、init.dスクリプトを複数用意しましょう。こだわりがなければapachectlのことは忘れましょう。

基本

httpd コマンドに、 「-f ファイル名」 オプションを渡すことができれば、別のhttpd.confで起動できます。別のhttpd.confの中では、PidFileやらポート周り(Listenとか)やら*2を変えておく必要があります。

ただし、Apacheを使ってる人ならわかると思いますが、httpdコマンドを直に呼ぶことはまずありません。apachectlコマンドとinit.d scriptを利用することになると思いますが、やっかいなことにデフォルトの状態ではこの二つのコマンドは、

  • ハードコーディング的(=コピペして直す必要がある)
  • 互いに依存してるわけではなく、どちらも直接httpdを呼ぶ(=両方修正が必要)
    • 理由は以下だそうです↓
# The semantics of these two functions differ from the way apachectl does
# things -- attempting to start while running is a failure, and shutdown
# when not running is also a failure.  So we just do it the way init scripts
# are expected to behave here.

と言う状態です。ですので、

  1. init.d script をコピペし、 httpdに「-f ファイル名」オプションを加える
  2. apachectlコマンドは捨てる(init.d scriptを使うか、直接httpdを叩く)

とするのがいいんじゃないかと思います。

debian packageの場合

さて、Ubuntuだとちょっと事情が変わります。upstream版と違って以下の特徴があります。

  • httpdはapache2、httpd.confはapache2.conf、apachectlはapache2ctlとなる*3
  • apache2ctl の中で、 APACHE_ARGUMENTS なる環境変数httpdへ渡している*4
  • init.d script の中から apache2 ではなく apache2ctl を呼んでいる
  • apache2.conf の中で、PidFileに環境変数APACHE_PID_FILEを使っている

ちょっと道具としては乏しいんですが、これらを使ってうまく頑張ればapache2ctlをいじらずに複数インスタンス起動用のinit.d scriptを作れます。

  1. init.d script をコピペ
    • PIDFILEを /etc/apache2/envvars じゃなくて新たなenvvarsから読むように修正
    • apache2ctlを呼ぶ際、環境変数APACHE_ENVVARS に上記のenvvarsファイルが入るようにする
  2. /etc/apache2/envvars をコピペ

この方法であれば、「APACHE_ENVVARS=envvarsのファイルパス apache2ctl」とすればapache2ctlも一応使えます。

ただし、debian packageだと init.dスクリプトがupstreamで用意されてる物より大きい*5ので、コピペするのにはちょっと抵抗があるかもしれません。その場合は、envvarsファイルだけ作って、後はapache2ctlを透過的に呼ぶような init.d スクリプトを自作しちゃったほうがすっきりするかもしれないです。

6/28 追記

同僚より「apachectl -f」使った方がいいんじゃないかと指摘を受けました。

このファイルの位置はコンパイル時に設定されますが、実行時に -f コマンドラインオプションを使って 位置を指定することもできます。例えば次のようにです。

/usr/local/apache2/bin/apachectl -f /usr/local/apache2/conf/httpd.conf

Apache の起動

ドキュメントに出ている安心な方法ですが、現実は以下のようにもうちょっと複雑です。

  • -f オプションを使うと、httpd への薄いラッパとして動作するようになるので、httpdの引数の仕様を知らないといけない
    • stopとかgraceful は -kオプションで指定
    • configtest は -tオプション
    • statusは利用不可(自分でコマンド作って打つ)
    • debianパッケージでは、start時にもうちょっと処理をやってるが、 -f による起動だとそれが無効になる
  • init.dスクリプトは、やっぱり自分で用意しなきゃならない*6

*1:mod_perlがメモリ食いまくるから。最近だとAPPとstaticなサーバは物理的に完全に分けちゃうだろうからあんまりやる人居ないかも。

*2:NFSに置くならLockFileも

*3:これはあんま関係ないけど

*4:この辺の事情かな?

*5:htcachecleanを実行するコードも混じっているため。

*6:-fを使わないときは「> 通常は、標準的な SysV init スクリプトとして動作するように設計されています。」ですが、-fオプションを使うとそうはならない