このサイトはMovable Typeを用いて構築しているのですが、Amazon Web Services内のEC2環境に移行する予定です。このサイトでは、実験も兼ねてHTTP/2を有効にしているのですが、EC2で標準配布されているパッケージではHTTP/2に対応していないため、再度ビルドを行い、動かすことに成功した手順の記録。
HTTP/2に無理やり対応しなくてもよいのでは?
この記事を読まれている方は『面倒なことをせずにyumで取得したい』と思われているかもしれません。現状では、無理に対応する必要はないと私も考えています。
HTTP/2をサポートしたWebブラウザの普及に伴い、今日ではHTTP/2を利用しているWebサイトも増えている。たとえばGoogleやFacebookなどは全面的にHTTP/2を有効にしているほか、Twitterなども一部でHTTP/2を利用している。とはいえ、現時点ではHTTP/2の導入が必須、というわけではない。Webアプリケーションなど動的にコンテンツを生成するようなWebサイトでは、アプリケーション側での対応なども必要となるため、HTTP/2が導入しにくいケースもある。Linuxディストリビューションでのサポートもまだ十分でない。
レンタルサーバーやホスティングサービスでは知っている方も多い、さくらインターネットが運営しているさくらのナレッジより引用しましたが、アプリケーション側での対応やLinuxディストリビューションでのサポートも十分ではないことから、対応させることは必要条件ではありません。
しかし、このサイトでは私自信の勉強や「最先端の技術で使えるのであれば使ってみたい」という好奇心もあり、有効にしています。
現状の問題点
今回、サーバーを変更するのには以下のような理由が挙げられます。
- サーバーのpingが落ちることが多い(監視サービスからサーバは落ちてないが、ダウンしていると通知が週に1〜2回、下手したら1日に1回来ることもあった)
- Movable Typeのデーモンがたまに再起動できなくなる(supervisordの設定などがうまくできていないか、スクリプトがうまく行っていない。プロセス自体は落ちていないので、supervisordの問題かも)
- EC2でReserved契約をしているのもかかわらず、放置している(色々あって腰が重たかった…)
3つ目の理由は私自信があと送りにしすぎ…ということもありますが、その他の理由はサーバーの乗り換えやMovable Typeの開発をしているSix Apartが提供しているMovable Type for AWS(AMI)を用いることで解決できると判断しました。
構築環境
今回の構築環境は以下のとおりです。
- Movable Type for AWS(AMI)をベースに取得
- OS: Amazon Linux
- 基本的なソフトウェアはepelレポジトリとシステムに含まれているレポジトリから取得
- Movable Typeに関してはSix Apartが提供しているレポジトリ
- インスタンスタイプ: t2.micro
構築時の問題点
先に、私が普段行っている流れを示します。
- nginxの公式リポジトリからSRPMパッケージ(ソースコードを含んだパッケージ)を取得
- OpenSSLの最新バージョンをtar形式で取得
- OpenSSLのバージョンなどを記述したSPECファイル(パッケージを制作するための情報が記述されているファイル)を編集する
- 再度ビルド
当初は自前で…といいますか、調べていた時にnginx with OpenSSL 1.0.2 (ALPN) on CentOS 7と出会いまして、スクリプトで回していました。
しかし、このやり方ではMovable Typeパッケージにおいて、nginxのperl関連のモジュールを採用しているため、関連のパッケージがないと言われました。
そのため、Amazon Linuxが配布しているオリジナルのパッケージからソースコードを取得して実行することにしました。
実際にビルドしてみる
その前に、ビルドする環境を整えます。以下のサイトにざっくりと書いてありますが、色々とエラー吐き出されたので以下に示します。
参考: Amazon Linux でのソースの入手と再ビルド | dogmap.jp
rpmbuildをインストールする
パッケージを作成するために必要なrpmbuildをインストールします。
$ sudo yum -y install rpmdevtools
$ sudo adduser mockbuild
$ sudo su - mockbuild
$ mkdir $HOME/rpmbuild $HOME/rpmbuild/SOURCES $HOME/rpmbuild/SPECS $HOME/rpmbuild/BUILD $HOME/rpmbuild/SRPMS $HOME/rpmbuild/RPMS $HOME/rpmbuild/RPMS/x86_64
$ echo "%_topdir $HOME/rpmbuild" >> $HOME/.rpmmacros
$ echo "%debug_package %{nil}" >> $HOME/.rpmmacros
mockbuildというアカウントを追加していますが、パッケージ取得時にroot権限や標準のec2-user権限で実行した場合、「mockbuildユーザーとグループではないよ」という忠告が出たためです。
おそらく、Amazon側でパッケージを作成する時にmockbuildというユーザーとグループで行っているのでしょう。
その上で、 get_reference_source
でパッケージを取得します。CentOSなどでは、yumdownloader
と呼ばれるものがあるなんて知らなかったです…(無知)
$ get_reference_source --package=nginx
$ rpm -ivh [File Path]
パッケージを取得すると、パッケージが保存された場所が表示されるので、それをコピーしておきます。コピーした保存場所は[File Path]
になりますので、適宜読み替えてください。
次に、OpenSSLのパッケージを取得します。今回はシステムには手を加えず、nginx側のみで対応するため、rpmbuild
フォルダ内にソースファイルを追加します。
$ cd ~/rpmbuild/SOURCE/
$ wget https://www.openssl.org/source/openssl-1.1.0f.tar.gz
その上で、SPECファイルを書き換えます。この記事では先述のスクリプトが非常に良くできているので、一部を変えた上で適応します。
cd ~/rpmbuild/SPECS/
sed -i "/Source12: .*/a Source20: https://www.openssl.org/source/openssl-1.1.0f.tar.gz" ./nginx.spec
sed -i "s|--with-http_ssl_module|--with-http_ssl_module --with-openssl=openssl-1.1.0f.tar.gz|g" ./nginx.spec
sed -i '/%setup -q/a tar zxf %{SOURCE20}' ./nginx.spec
sed -i '/.*Requires: openssl.*/d' ./nginx.spec
# hardening whatnots since 1.11.9
sed -i 's|%define WITH_LD_OPT .*|%define WITH_LD_OPT ""|g' ./nginx.spec
sed -i 's| -fPIC||g' ./nginx.spec
sedコマンドでファイルの場所とマッチしたところを置換しています。ちなみに、1行目と3行目は追加しているみたいです。
その後にrpmbuildするとパッケージが生成されます。
$ rpmbuild -ba nginx.spec
生成には時間がかかるため、その間にストレッチでもしておきましょう。
生成が終了すると、/home/mockbuild/rpmbuild/RPMS/x86_64/
以下にrpmファイルが追加されています。
mockbuildユーザーからログアウトし、ec2-user内の適当なディレクトリにrpmファイルをコピーしてアプリケーションをインストールします。
Movable TypeのAMIを利用している場合はnginxが既にインストールしているため、一度アンインストールした後に再度インストールします。2017年6月21日現在では、データの削除などはありませんでした。
$ mkdir RPMS
$ sudo cp -r /home/mockbuild/rpmbuild/RPMS/x86_64 ./
$ sudo chown ec2-user:ec2-user -R ./x86_64
$ sudo yum remove nginx -y
$ cd x86_64
$ sudo yum install *
$ sudo yum install movabletype
nginxのインストールは終了しましたが、このままだと新しいバージョンが出るたびにyumでアップデートされてしまうため、レポジトリの情報が記述されているファイルに追記します。
以下のファイルを編集します。
$ sudo vi /etc/yum.repos.d/amzn-main.conf
# 最初のセクションの最終行に以下を追記
exclude=nginx*
$ sudo vi /etc/yum.repos.d/epel.conf
# 最初のセクションの最終行に以下を追記
exclude=nginx*
ファイルを保存したら作業は終了です。
あとがき
新しいバージョンが出るためにamzn-mainレポジトリも更新されると思いますので、そのあたりは各自で確認するなり、nginxのメーリングリストを購読して確認する必要があると思います。
また、Amazon Linuxは一定期間内で一度アップデートがあるため、そのあたりも常に追う必要があります。
今後、もしかしたらOpenSSLのバージョンなどがアップデートされると、この作業も必要ないかもしれません。