Apache2 と PHP5 を使って、Raspberry Pi でホームページ公開を実験してみます。
環境はありがちなNTT東の光(フレッツのネクスト、ひかり電話ルーター)で、宅内LAN設置のRaspberry PiをNAPT=IPマスカレードにて外部公開します。
URLは、独自ドメイン取得で取得したドメインを使い www.angelcurio.com とします。
例によってなるべくSDカードへの書き込みが発生しないように工夫します。
(といいつつ、結局外付けHDDを増設することになりました。)
主な方針
実験の結果は、現在ご覧のホームページ、ということです。
主な内容
ApacheはRaspberry Pi の1号機 (192.168.1.20) で動かすことにします。
また、後述の dnsmasq も同じホストで動かします。
ネットワーク環境は、フレッツネクスト(Bフレッツから自動昇格)、光ルーターはPR-200NEです。
実行例のプロンプトは 「#」スーパーユーザを、「$」は一般ユーザーを表します。
symlink はシンボリックリンクのことです。
設定変更により作成・変更したファイル・ディレクトリなど。
/var/exhdd/apache2/ /usr/local/apache2/ -> /var/exhdd/apache2/ /etc/init.d/apache2-me /etc/apache2-me -> /usr/local/apache2/conf/ /usr/local/apache2/bin/ /usr/local/apache2/bin/apache2ctl-me -> /usr/sbin/apache2ctl /usr/local/apache2/bin/a2ensite-me -> /usr/sbin/a2ensite /usr/local/apache2/bin/a2dissite-me -> /usr/sbin/a2dissite /usr/local/apache2/bin/a2enmod-me -> /usr/sbin/a2enmod /usr/local/apache2/bin/a2dismod-me -> /usr/sbin/a2dismod /etc/logrotate.d/apache2-me
下記コマンドにより一発で導入できます。楽ちんだなあ。
# apt-get install apache2 php5
パッケージの細かい指定は忘れてしまいましたが(確か何回かapt-get installをやったような・・・)、結果として下記のパッケージをインストールしました。もしかしたら全部はいらないかも。
apache2 2.2.22-13+deb7u4 Apache HTTP Server metapackage apache2-mpm-prefork 2.2.22-13+deb7u4 Apache HTTP Server - traditional non-threaded model apache2-utils 2.2.22-13+deb7u4 utility programs for webservers apache2.2-bin 2.2.22-13+deb7u4 Apache HTTP Server common binary files apache2.2-common 2.2.22-13+deb7u4 Apache HTTP Server common files libapache2-mod-php5 5.4.36-0+deb7u3 server-side, HTML-embedded scripting language (Apache 2 module) libapr1 1.4.6-3+deb7u1 Apache Portable Runtime Library libaprutil1 1.4.1-3 Apache Portable Runtime Utility Library libaprutil1-dbd-sqlite3 1.4.1-3 Apache Portable Runtime Utility Library - SQLite3 Driver libaprutil1-ldap 1.4.1-3 Apache Portable Runtime Utility Library - LDAP Driver libsvn1:armhf 1.7.5-1+rpi1 Shared libraries used by Apache Subversion php-doc 20100521-2 Documentation for PHP5 php5 5.4.36-0+deb7u3 server-side, HTML-embedded scripting language (metapackage) php5-cgi 5.4.36-0+deb7u3 server-side, HTML-embedded scripting language (CGI binary) php5-cli 5.4.36-0+deb7u3 command-line interpreter for the php5 scripting language php5-common 5.4.36-0+deb7u3 Common files for packages built from the php5 source
※上記バージョンは 2015年2月2日現在のものです。
たまたま家に転がっていた古いHDD(40GB、パラレルATA)を、これまた家に転がっていた
ATA->USB変換器を使って接続し、その中にapache2の環境を構築します。
まずは、各々の骨董品を接続しますが、御多分にもれずうちのRaspberryp Piも、「USBポートに機器を挿すとその瞬間に再起動がかかってしまう」病(勝手に命名)なので、本体のUSBポートにはあらかじめUSBハブを挿してあります(キーボードやマウスは抜き差ししても問題ないんだけどねぇ)。
今回HDDを運用するということで、念のためセルフパワーのUSBハブを選択しました(ATA->USB変換器にもACアダプターがついているので、バスパワーのハブでもいいんだろうけれども・・・)。
ここでパーティションとファイルシステムを作成する、のですが、ページの趣旨からずれてしまうので、下記ページに分けました。
[外付けHDDの接続]
というわけで、外付けHDDを /var/exhdd へマウントした状態になりました。
次に、Apache2のベースとなるディレクトリ /var/exhdd/apache2/ を作成します。
同時に、/usr/local/apache2/ の名称でsymlinkを作成し、以降は、/usr/local/apache2/ を使用するようにします。
# mkdir /var/exhdd/apache2 # ln -s /var/exhdd/apache2 /usr/local/apache2
外部公開するURLは下記とし、apache2の仮想ホストとして定義します(2015-06-15現在)。
なおこれは独自ドメインとして取得しています(独自ドメイン取得を参照)。
また、Apacheのデフォルトサイト(http://IPアドレス/でアクセスできる)は運用せず、アクセスがあっても常にエラーになるように(無作為の攻撃がうるさそうなので、コンテンツは一切置かないことに)します。
実際の設定については、以降で説明します。
まずはApache2から。
オリジナルの起動スクリプト /etc/init.d/apache2 の末尾に -XXX(マイナス記号と任意の文字列)を付加したものを新たにコピーとして作成します。
こうすることで、apache2 の設定ファイルとして /etc/apache2/ ではなく /etc/apache2-XXX/ のものを使って起動してくれるようです。
今回は -XXX の部分は -me を使用することにします。
ついでに OS立ち上げ時の自動実行も設定します。
オリジナルは何も触らずにそのまま残すようにして、立ち上がらないようにだけしておきます。
# cp /etc/init.d/apache2 /etc/init.d/apache2-me # chkconfig --add apache2-me # chkconfig --del apache2 #オリジナルが起動しないようにする # /etc/init.d/apache2 stop #オリジナルが起動していれば停止
上記の chkconfig コマンドは、chkconfig パッケージをインストールすると使えるようになります。Debian 的には insserv を使うのが本筋なのでしょうが、管理人的に chkconfig になれきってしまっているため、chkconfig を使用しております。
重要
上記の /etc/init.d/apache2-me ですが、下記の修正をしておかないと、次回 apt-get update/upgrade の際に
apache2.2-common のアップデートの際にスクリプトの実行エラーが発生するようになってしまいますのでご注意を!!
修正ファイル:
/etc/init.d/apache2-me
修正内容(diffの結果):
# diff apache2 apache2-me 3c3 < # Provides: apache2 --- > # Provides: apache2-me
さて、Apache2 に含まれるいくつかの便利なコマンドについても、下記のように別名でsymlink を作成しておきます。
すると、先ほどの起動スクリプトの末尾に -XXX を付加したのと同じ効果(別の設定ファイルを使ってくれる)が得られます。
# mkdir /usr/local/apache2/bin # cd /usr/local/apache2/bin # ln -s /usr/sbin/a2dismod a2dismod-me # ln -s /usr/sbin/a2dissite a2dissite-me # ln -s /usr/sbin/a2enmod a2enmod-me # ln -s /usr/sbin/a2ensite a2ensite-me # ln -s /usr/sbin/apache2ctl apache2ctl-me
これらのコマンドを使う際は、上記のものを使うようにします。
(上記のシンボリックリンクを /usr/sbin/ に作ってしまったほうがよいかもしれません。各自のお好みでどうぞ。)
前述の並列環境構築の続きです。
並列環境用の設定ファイルディレクトリとして /etc/apache2-me/ を作りたいところですが、/etc/apache2-me/ は symlink として作成し、その実体は HDD上の /usr/local/apache2/conf となるようにします。
実験と称して設定ファイル類を頻繁にいじくる可能性があるため、SDカードへの書き込みをなるべく減らしたい、という意図です。
/usr/local/apache2-me/conf の内容は、ひとまず /etc/apache2/の中身をコピーしておきます。
また、オリジナルの設定ファイルは使いません。
# ln -s /usr/local/apache2/conf /etc/apache2-me # cp -pR /etc/apache2/* /usr/local/apache2/conf # chmod 000 /etc/apache2/ #オリジナルの設定ファイル参照禁止(動作確認用)
(2015-06-15追記)
/usr/local/apache2/conf/ (/var/exhdd/apache2/conf/) の一部ディレクトリは、オリジナルを指すように symlink としました。
こうすることで、パッケージがアップグレードした場合にも設定ファイルをコピーしなおす必要がないためです。
# cd /usr/local/apache2/conf # mv conf.d envvars magic mods-available /tmp/ # /tmpへ移動してあとで削除 # ln -s /etc/apache2/conf.d . # ln -s /etc/apache2/envvars . # ln -s /etc/apache2/magic . # ln -s /etc/apache2/mods-available .
(2015-06-15追記ここまで)
ドキュメントルートは、仮想ホストごとに下記ディレクトリを作成して使うことにします。
仮想ホスト | ドキュメントルート | 仮想ホスト用の設定ファイル(ディレクトリ /usr/local/apache2/conf/sites-available/) | 備考 |
デフォルト(仮想ではない) | /usr/local/apache2/www-default/ | default | デフォルト(常にエラーを表示させる) |
www.angelcurio.com | /usr/local/apache2/vhost-angelcurio/ | vhost-angelcurio-www | 外部公開用ホスト |
xxx.yyy(非公開) | /usr/local/apache2/vhost-xxx/ | vhost-xxx | 制限付き公開(すみませんが非公開) |
上記の設定ファイルの有効化/無効化(symlinkの作成、削除)は、下記のコマンドで自動的に行ってくれます。
引数は、/usr/local/apache2/conf/sites-available/ の各ファイル名となっています。
有効化すると、 /usr/local/apache2/conf/sites-enabled/ の下に、対応する設定ファイルへの symlink が作成されます。
とりあえず、前述の3つを有効化しておきます。
# /usr/local/apache2/bin/a2ensite-me default # /usr/local/apache2/bin/a2ensite-me vhost-angelcurio-www # /usr/local/apache2/bin/a2ensite-me vhost-xxx # ls /usr/local/apache2/conf/sites-enabled # ls -o /usr/local/apache2/conf/sites-enabled/ 合計 0 lrwxrwxrwx 1 root 26 2月 11 22:42 000-default -> ../sites-available/default lrwxrwxrwx 1 root 34 1月 19 00:24 vhost-andromeda -> ../sites-available/vhost-andromeda lrwxrwxrwx 1 root 35 1月 29 15:48 vhost-angelcurio-www -> ../sites-available/vhost-angelcurio-www
(備考:defaultのサイトのみ、symlink の名称が 000-default になります。)
/var/log/ を tmpfs としているため、マシンが再起動するたびに /var/log/ がクリアされた状態となるため、
Apache2 のアクセスログ格納ディレクトリも毎回消えてしまいます。
そこで、Apache2起動時に /var/log/ 下にapache2用のディレクトリを作成するようにします。
修正ファイル:
/etc/init.d/apache2-me
修正内容(diffの結果):
#diff /etc/init.d/apache2 /etc/init.d/apache2-me 3c3 < # Provides: apache2 --- > # Provides: apache2-me 41a42,47 > #make log dir automatically (because of /var/log is tmpfs) > apache2logdir=/var/log/apache2$DIR_SUFFIX > if [ ! -d $apache2logdir ] ; then > mkdir $apache2logdir > chgrp adm $apache2logdir > fi
オリジナルのログローテーション用定義ファイルをコピーして、一部修正します。
# cp /etc/logrotate.d/apache2 /etc/logrotate.d/apache2-me
修正内容(行番号はご参考):
8c10 < create 640 root adm --- > # create 640 root adm 11c13,14 < /etc/init.d/apache2 reload > /dev/null --- > /etc/init.d/apache2-me status > /dev/null && \ > /etc/init.d/apache2-me graceful > /dev/null
補足:オリジナルではローテーションの際に reload を指定しているが、これだと、
Apache2 が停止状態なのに、ログローテーションしたら Apache2 が勝手に起動してしまった
となってしまうので、上記のように
ステータスをチェックして、起動している場合にのみ graceful で再起動
に変更してみました。
その他の条件はお好みで。
変更の趣旨は、PHPのセッション管理に使用する(と思われる)ワークディレクトリの場所をSDカード上からHDD上へ変更する、です。
それ以外は特に変更しませんでした。
# diff /etc/php5/apache2/php.ini.orig /etc/php5/apache2/php.ini 1342c1342 < ;session.save_path = "/var/lib/php5" --- > session.save_path = "/usr/local/apache2/php5session"
PHP5のセッションディレクトリを変更したので、crontab のクリーンアップスクリプト /etc/cron.d/php5 もそれに合わせて修正します。
ついでにPHP5のセッションファイルのクリーンアップの頻度を下げます。
デフォルトでは毎時9分と39分の30分間隔ですが、6時間間隔にします。
このあたりはお好みでどぞ。
# cat /etc/cron.d/php5 # /etc/cron.d/php5: crontab fragment for php5 # This purges session files older than X, where X is defined in seconds # as the largest value of session.gc_maxlifetime from all your php.ini # files, or 24 minutes if not defined. See /usr/lib/php5/maxlifetime # original # Look for and purge old sessions every 30 minutes #09,39 * * * * root [ -x /usr/lib/php5/maxlifetime ] && \ # [ -x /usr/lib/php5/sessionclean ] && [ -d /var/lib/php5 ] && \ # /usr/lib/php5/sessionclean /var/lib/php5 $(/usr/lib/php5/maxlifetime) 39 */6 * * * root [ -x /usr/lib/php5/maxlifetime ] && \ [ -x /usr/lib/php5/sessionclean ] && [ -d /var/exhdd/apache2/php5session ] && \ /usr/lib/php5/sessionclean /var/exhdd/apache2/php5session $(/usr/lib/php5/maxlifetime)
外部公開時の名前解決は、独自ドメイン取得で少し触れた MyDNS.JPで問題ないのですが、自宅内LANからサーバー名を使って自分のところのサーバーへアクセスしようとしたとたん、問題が発生します。
おおよそ以下のようなことが起こります。
しょうがないので・・・dnsmasq でなんとかごまかします。
主な方針とか、動作概要とか。
dnsmasqをインストールします。apt-get install でよいと思います。
dnsmasqの設定ファイルを下記のように修正します。
# cd /etc # cp -p dnsmasq.conf dnsmasq.conf.orig # vi dnsmasq.conf # diff dnsmasq.conf.orig dnsmasq.conf 46c46 < #no-resolv --- > no-resolv 112c112 < #no-hosts --- > no-hosts
補足:
/etc/resolv.conf, /etc/hosts を読まないように、という指示です。
次に、下記のファイルを新規作成します。
ファイル名:/etc/dnsmasq.d/angelcurio.com
内容:
# can use regular expressions address=/angelcurio.com/192.168.1.20
補足:
ホスト名の末尾が angelcurio.com にマッチする問い合わせに対してはすべて 192.168.1.20 と回答せよ、という意味です。
最後に dnsmasq を再起動します。
# /etc/init.d/dnsmasq restart
dnsmasq自体を単体で動作確認。
$ dig +short www.angelcurio.com @192.168.1.20 192.168.1.20
光ルーターで下記を変更します。
タイトルは、PR-200NEの設定画面のタイトルそのままです。
設定変更が終わったら、保存ボタンを忘れずに押します(でないと停電等で再起動したら、変更前に戻ってしまいますyo)。
WAN側のポート80番(WWW)へのアクセスが、192.168.1.20 の 80番(WWW)へ転送されるようにします。
「LAN側DNSサーバアドレス」という項目の「プライマリDNS」欄に、dnsmasq が動いているホストのアドレス 192.168.1.20 を入力します。
エントリーを1つ追加します。
指定内容は下記の通りです。
こうすると、宅内から*.angelcurio.comにマッチするホスト名を問い合わせた場合に、前節の「プライマリDNS」で指定したDNSサーバーへ問い合わせに行く、という動作になります。
現在ご覧の http://www.angelcurio.com/raspberrypi/ つまりこのページというわけです。
大急ぎでまとめたので、雑なページになってしまいましたとさ。
おしまい。