LAMP環境をソースからビルドしてみた(Apache編)

 先日、某企業様の選考エントリー課題として、「LAMP環境のソースインストール」というものをいただきました。
 僕としても初めての試みということもあり、せっかくなので今回から「LAMP環境をソースからビルドしてみた」シリーズとして連載記事にその記録を残していこうと思います。
 また、根本的な理解を深めるという側面もあるので、基本的に公式ドキュメントなどの一次情報を参考にして作業を進めていきます。(英語文献を読むのも頑張っていきたい...)
Compiling and Installing - Apache HTTP Server Version 2.4

作業環境

  • OS: Ubuntu Server 20.04 (@VBox VM)
  • RAM: 8GB
  • NIC: Bridge Adaptor

ソースコードの入手・展開

 まず初めに、Apacheのサイトでこれからビルドしていくソースコードを入手してきます。

$ curl https://dlcdn.apache.org//httpd/httpd-2.4.51.tar.gz -o httpd-2.4.51.tar.gz

 SHA256ハッシュで整合性をチェックします。

$ curl https://downloads.apache.org/httpd/httpd-2.4.51.tar.gz.sha256 -o httpd-2.4.51.tar.gz.sha256
$ sha256sum -c httpd-2.4.51.tar.gz.sha256
httpd-2.4.51.tar.gz: OK

 gzip, tarで展開して、さっそくワーキングディレクトリを移動していきます。

$ gzip -d httpd-2.4.51.tar.gz
$ tar xvf httpd-2.4.51.tar
$ cd httpd-2.4.51

依存関係の解決

 ソースをただ持ってきてmakeを叩いただけではインストールはできません。公式ドキュメントのRequirementsにも書いてある通り、Apacheを動かすために外部パッケージの設定を行っていく必要があります。

APRAPR_Util

The mission of the Apache Portable Runtime (APR) project is to create and maintain software libraries that provide a predictable and consistent interface to underlying platform-specific implementations.
引用: https://apr.apache.org/
(APRの使命は、プラットフォーム特有の実装にとらわれない一貫性を提供するライブラリを作成し、維持することです。)

 この文章からもわかる通り、APRApacheを動かすために必要なランタイムです。READMEファイルを見た限り、原子性を満たす操作やメモリ・プロセスの管理、ファイル・ネットワークの入出力などを行っているようです。
 こちらもApache本体の時と同じように、ソースとハッシュを持ってきて整合性をチェックし、展開していきます。

APR
$ curl https://dlcdn.apache.org//apr/apr-1.7.0.tar.gz -o apr-1.7.0.tar.gz
$ curl https://downloads.apache.org/apr/apr-1.7.0.tar.gz.sha256 -o apr-1.7.0.tar.gz.sha256
$ sha256sum -c apr-1.7.0.tar.gz.sha256
apr-1.7.0.tar.gz: OK
$ gzip -d apr-1.7.0.tar.gz
$ tar xvf apr-1.7.0.tar
APR-Util
$ curl https://dlcdn.apache.org//apr/apr-util-1.6.1.tar.gz -o apr-util-1.6.1.tar.gz
$ curl https://downloads.apache.org/apr/apr-util-1.6.1.tar.gz.sha256 -o apr-util-1.6.1.tar.gz.sha256
$ sha256sum apr-util-1.6.1.tar.gz.sha256
apr-util-1.6.1.tar.gz: OK
$ gzip -d apr-util-1.6.1.tar.gz
$ tar xvf apr-util-1.6.1.tar

 あとは、これらのソースを~/httpd-2.4.51/srclib内に移動すればOK。ただし、ディレクトリ名のバージョンを表す数字は消しておきます。

$ mv apr-1.7.0/ httpd-2.4.51/srclib/apr
$ mv apr-util-1.6.1/ httpd-2.4.51/srclib/apr-util

PCRE (Perl-Compatible Regular Expressions)

 名前の通り、Perl互換の正規表現を扱うためのパッケージです。github上で公開されている最新バージョンを持ってきます。

$ curl -L https://github.com/PhilipHazel/pcre2/releases/download/pcre2-10.39/pcre2-10.39.tar.gz -o pcre2-10.39.tar.gz
$ curl -L https://github.com/PhilipHazel/pcre2/releases/download/pcre2-10.39/pcre2-10.39.tar.gz.sig -o pcre2-10.39.tar.gz.sig

 PCREのパッケージはGPG鍵で署名されているので、検証は以下のように行いました。

$ gpg --verify pcre2-10.39.tar.gz.sig 
gpg: assuming signed data in 'pcre2-10.39.tar.gz'
gpg: Signature made Fri Oct 29 16:07:03 2021 UTC using RSA key 45F68D54BBE23FB3039B46E59766E084FB0F43D8
gpg: Can't check signature: No public key

 公開鍵がないと怒られたので、公開鍵を取得してきてからもう一度署名を検証します。

$ gpg --keyserver pgp.nic.ad.jp --recv-key 45F68D54BBE23FB3039B46E59766E084FB0F43D8
$ gpg --verify pcre2-10.39.tar.gz.sig
...
gpg: Good signature from "Philip Hazel <ph10@hermes.cam.ac.uk>" [unknown]
...

 検証が完了したら、いままでと同様に展開していきます。

$ gzip -d pcre2-10.39.tar.gz
$ tar xvf pcre2-10.39.tar

 展開が完了したら、PCREのREADMEに書いてある通りにインストールしていきます。/usr/local/ 以下のファイル操作でPermission Deniedされることがあるので、sudoをつけてmakeしていきます。

$ cd pcre2-10.39
$ ./configure
$ sudo make
$ sudo make install 

ANSI-Cコンパイラとビルドツール

$ make -v
GNU Make 4.2.1
(略)
$ gcc -v
(略)
gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)

正確な時刻

 systemd-timesyncdをインストールしてNTPで時刻設定を行います。
 私の環境ではルータ(192.168.11.1)がNTPサーバの役割も受け持っているので、そこに同期する形で時刻を合わせていきます。

$ sudo apt install systemd-timesyncd
$ sudo vim /etc/systemd/timesyncd.conf 
(↓のようにConfファイルを編集する)
[Time]
NTP=192.168.11.1
$ sudo systemctl unmask systemctl-timesyncd
$ sudo systemctl enable systemd-timesyncd
$ sudo systemctl start systemd-timesyncd
$ sudo timedatectl set-ntp true  // NTPでの同期を有効化
$ sudo timedatectl set-timezone Asia/Tokyo // タイムゾーンをUTC+9に
$ timedatectl
(略)
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active

ソースツリーの構築とビルド(エラーとの闘い)

 ここまででインストールに必要なライブラリやパッケージの導入や、事前に済ませておくべき設定はすべて完了しました。これにてようやくApache本体のインストールに取り掛かっていきます。
 はじめに、ソースツリーをUbuntu向けに構成していきます。

$ ./configure

 実行すると作業状況などのログがダーーーーっと流れていきます。不足しているパッケージなどがある場合は最後の行に出力されます。成功した場合はバージョンやインストール先、システムのコンパイラ情報などが表示されているはず。
 無事終了したら、makeでビルドしていきます。
 これでうまくいくかと思いきや、エラー発生。APR関係の処理のあたりでexpat.hがないと怒られてしまいました。 というわけでこちらもソースからインストール。

$ curl -L https://github.com/libexpat/libexpat/releases/download/R_2_4_2/expat-2.4.2.tar.gz -o expat.tar.gz 
$ gzip -d expat.tar.gz
$ tar xvf expat.tar
$ cd expat
$ ./configure
$ sudo make
$ sudo make install

 今度こそ上手く行くかと思ったのですが、PCREまわりでエラー発生。ここでとても詰まりました。
 結論から言ってしまうと、PCRE2ではなくPCREをインストールする必要があったということがわかりました。公式サイトにEnd of lifeなどと書いてあったので、何も考えずに最新版を入れてしまったのが間違いでした。
 ということで、PCRE2をアンインストールしてからPCREを入れなおします。

$ cd pcre2-10.39
$ sudo make uninstall
$ cd
$ curl -L -o pcre-8.45.tar.gz https://sourceforge.net/projects/pcre/files/pcre/8.45/pcre-8.45.tar.gz/download
$ gzip -d pcre-8.45.tar.gz
$ tar xvf pcre-8.45.tar
$ cd pcre-8.45
$ ./configure
$ sudo make
$ sudo make install

これでOK。もう一度httpdディレクトリにもどって作業を進めていきます。

$ ./configure --with-pcre=/usr/local
$ sudo make
$ sudo make install

お疲れさまでした。これにてインストールは終了です。

httpdの起動

 インストールも終わったので、さっそくApacheを動かしていきましょう。 公式ドキュメントによると、apachectlで起動できるらしい。PATHを通してからやっていきます。

$ export PATH=$PATH:/usr/local/apache2/bin
$ sudo apachectl -k start
/usr/local/apache2/bin/httpd: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory

 ライブラリが読み込めてないとのこと。調べてみたら、新たなライブラリを追加したときはldconfigでキャッシュとかリンキングをしなおしてあげる必要があるらしい。初めて使うコマンドでした。
気を取り直してもう一回。

$ sudo apachectl -k start
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using (サーバのIPv6アドレス). Set the 'ServerName' directive globally to suppress this message

 どうやらうまく動いてはいるのですが、サーバ名が指定されてないと警告が表示されました。毎度毎度このメッセージが出るのはうっとうしいので、httpd.confにサーバ名を設定します。
 あとはapachectl -k stopしてから再起動すれば、なにも表示されないでコマンドが通るはず。
 サーバにHTTPでアクセスしたら見慣れた画面とは違うページが表示されはしたものの、無事動作が確認できました。"It works!"の文字にここまで感動したのは初めてかもしれない。
f:id:KLag:20211227044259p:plain

まとめ

 sudo apt install apache2で済むようなことが、ソースコードからビルドするととても大変だということが身にしみてわかりました。これから毎日aptに感謝しながら生活したいと思います。
 それ以上に、今までLinuxを利用する中で触ってこなかった/usr/local/lib/usr/local/includeといったディレクトリにシステム全体で共有されるライブラリとかヘッダファイルが置いてあることや、単純にApache一つをとっても様々なライブラリとの依存関係があることが理解できました。
 また、今までソースからビルドする方法に関しては皆目見当がつかなかったのですが、今回の構築を通じて大まかな流れに関しては掴めたかなと思います。
 今回はここまでです。次回はここにPHPをインストールしていきたいと思います。ではまた。