🙆‍♀️

Amazon Linuxにインストール済のミドルウェアをAmazon Linux2023にインストールする

2023/12/08に公開

自己紹介

こんにちは。株式会社DELTAでインフラエンジニアをしている浜崎です。
この記事は Linux Advent Calendar 2023 の8日目の記事となります。

はじめに

タイトルにある通りですが、Amazon Linux(以下、AL)にインストール済のミドルウェアを、バージョンを維持したままAmazon Linux2023(以下、AL2023) にもインストールできないかな?と思い、検証してみました。

きっかけは、運用中のEC2のAMIをAL からAL2023にアップグレードしたい、ただし中で動いている主要なミドルウェアのバージョンは変更せずに維持したいという要件があったことです。

残念ながら、ALからAL2023へのインプレースアップグレードはサポートされていません。
そのため、新規にAL2023を立ち上げて環境を構築する必要があります。

そこで、そもそもAL2023に古いバージョンのミドルウェアってインストールできるのか?と思い、試してみました。

前提として、ALで動いているミドルウェア/バージョンはこちらです。
nginx1.18.0, PHP7.3.30

結論

すべてをパッケージからインストールすることはできませんでしたが、バージョン指定のあるnginx1.18.0, PHP7.3.30をソースからビルドすることでインストールできました。

当初は指定のバージョンのミドルウェアをすべてパッケージからインストールできないかと検討しましたが、標準で設定されているリポジトリには該当バージョンのパッケージはなく、AL2023 は EPEL に対応していないことからRemiリポジトリからのインストールもできませんでした。

パッケージがないなら無理かと諦めかけましたが、指定したバージョンのソースをミドルウェアの公式サイトからをダウンロードし、それをビルドすることでインストールできました。

各ミドルウェア インストールの流れ

※最初に注意ですが、PHPをソースからインストールする場合は、AL2023のEC2のインスタンスタイプは2G以上のものを選択してください。1GBのt2.smallで検証した際、PHPビルド時にメモリ不足によるエラーが発生しました。

詳細は後段に記載しますが、インストールの流れとしては以下になります。
対象ミドルウェアはnginx1.18.0, PHP7.3.30で、大まかな流れとしてはどちらも同様です。

  1. ユーザとグループの追加
    ミドルウェアを専用に扱うため、新しいユーザとグループを追加します。
  2. ミドルウェアのソースダウンロードと展開
    ミドルウェアの公式サイトからtarファイルをダウンロードし、展開します。
  3. ALでの設定確認
    ALで動作中のミドルウェアの設定を確認します。
    移行後のAL2023で同じ設定を使うことで、設定の一貫性を保ちます。
  4. 必要なライブラリのインストール
    初めはどのライブラリが必要かが不明です。
    ソースを展開してできたディレクトリに移動した状態で"./configure"を実行して、必要なライブラリが足りない場合は以下のような出力がされます。この出力された結果に基づいてライブラリを逐次インストールします。(※この例ではgdが足りないといわれています)
./configure: error: the HTTP image filter module requires the GD library.
You can either do not enable the module or install the libraries.
  1. ビルド
    "./configure"実行によって作成されたMakeファイルを使用して、ミドルウェアをビルドします。
    ソースからビルドする際、systemdの登録は手動で設定する必要があります。

事項から、それぞれのインストール手順を記載します。

nginx1.18.0 インストール

まずはOpenSSL 1系をインストール

AL2023にはデフォルトでOpenSSL3系がインストールされています。
ですが、インストールしたいnginx1.18.0と互換性がないことから、OpenSSL1系をインストールします。

最初にコンパイルに必要なgccをインストールします。

sudo dnf install gcc

該当ミドルウェア/バージョンのtarファイルをダウンロードして展開します。

cd /usr/local/src
sudo wget https://www.openssl.org/source/openssl-1.1.1u.tar.gz
sudo tar -xzvf ./openssl-1.1.1u.tar.gz

必要なライブラリをインストールします。

sudo dnf install perl-FindBin perl-open perl-YAML perl-YAML-Tiny perl-File-HomeDir perl-Unicode-LineBreak perl-lib perl-File-Compare perl-File-Copy

展開してできたフォルダに移動してビルドします。

cd openssl-1.1.1u
sudo ./config --prefix=/usr/local/ssl
sudo make
sudo make install

これでインストール完了ですが、このままではデフォルトのOpenSSL3系が利用されています。
OSが参照する先を、今回インストールしたものに変更します。

# 既存の参照先を移動する
sudo mv /usr/bin/openssl /usr/bin/openssl.bak
# インストールしたOpenSSLを参照するようシンボリックリンクを作成する
sudo ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl

これで完了のはずですが、バージョン確認で以下のようなエラーが出ます。

sh-5.2$ sudo openssl version
openssl: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory

「libssl.so.1.1」が見つからないとのことなので、存在を確認しldconfigにパスを追加します。

sh-5.2$ sudo find / -name "libssl.so.1.1"
/usr/local/ssl/lib/libssl.so.1.1
sh-5.2$ sudo sh -c "echo "/usr/local/ssl/lib/" >> /etc/ld.so.conf.d/dyninst-x86_64.conf"
sh-5.2$ sudo ldconfig

インストールしたバージョンが出力されれば成功です

sh-5.2$ sudo openssl version
OpenSSL 1.1.1u  30 May 2023

nginx1.18.0をインストール

nginx1.18.0をインストールします。

まずは、nginxのユーザ、グループを作成し、tarファイルをダウンロードして展開します。

sudo groupadd nginx
sudo useradd -g nginx nginx

cd /usr/local/src
sudo wget http://nginx.org/download/nginx-1.18.0.tar.gz
sudo tar -xzvf nginx-1.18.0.tar.gz

必要なライブラリをインストールします。

sudo dnf install gd-devel perl-ExtUtils-Embed gperftools-devel pcre-devel libxslt-devel

GeoIP-develも必要ですが、AL2023標準リポジトリにないため、fedora36のリポジトリを指定してインストールします。
まずはrepoファイルを追加します。

sudo vi /etc/yum.repos.d/fedora.repo

内容は以下を記載します。

[fedora]
name=Fedora 36 - $basearch
#baseurl=http://download.example/pub/fedora/linux/releases/36/Everything/$basearch/os/
metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-36&arch=$basearch
enabled=0
metadata_expire=7d
repo_gpgcheck=0
type=rpm
gpgcheck=0

追加したリポジトリを指定してインストールします。

sudo dnf --disablerepo=* --enablerepo=fedora install GeoIP-devel

インストール時に必要な設定の確認です。
移行前のALでバージョン確認コマンドを実行し、「configure arguments」の部分が必要な設定になります。

sh-4.2$ nginx -V
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --with-compat --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-stream_ssl_preread_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --with-ld-opt=' -Wl,-E'

※ALの設定と合わせるため、一部ディレクトリを作成します。

sudo mkdir -p /var/lib/nginx/tmp/client_body

展開してできたフォルダに移動してビルドします。
「./configure」実行の際に前もって確認していた設定を指定します。(※OpenSSLを別途インストールしているため--with-opensslのみ追加します)

cd nginx-1.18.0
sudo ./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --with-compat --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-stream_ssl_preread_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic' --with-ld-opt=' -Wl,-E' --with-openssl=/usr/local/src/openssl-1.1.1u
sudo make
sudo make install

最後に自動起動の設定をします。
systemdサービスファイルの追加し、以下を記載します。

sudo vi /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/kill -s HUP \$MAINPID
ExecStop=/bin/kill -s QUIT \$MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

※参考:サービスファイルの内容は以下を参照しました。
http://mogile.web.fc2.com/nginx_wiki/nginx_wiki201510/start/topics/examples/systemd.html

サービス開始、自動起動有効化します。ステータスを確認し起動していれば成功です。

sudo systemctl start nginx
sudo systemctl enable nginx
sh-5.2$ sudo systemctl status nginx
● nginx.service - nginx - high performance web server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Tue 2023-12-05 02:02:54 UTC; 1min 5s ago
       Docs: http://nginx.org/en/docs/
   Main PID: 68365 (nginx)
      Tasks: 2 (limit: 1114)
     Memory: 5.4M
        CPU: 21ms
     CGroup: /system.slice/nginx.service
             ├─68365 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf"
             └─68366 "nginx: worker process"
sh-5.2$ sudo systemctl is-enabled nginx.service
enabled

PHP7.3.30 インストール

PHP7.3.30をインストールします。
改めての補足ですが、AL2023のEC2のインスタンスタイプは2G以上のものを選択してください。1GBの場合PHPビルド時にメモリ不足によるエラーが発生します。

グループ、ユーザを追加し、tarファイルをダウンロードして展開します。(移行前の環境に合わせphp-fpmユーザ、グループを作成します)

sudo groupadd php-fpm
sudo useradd -g php-fpm php-fpm

cd /usr/local/src
sudo wget https://www.php.net/distributions/php-7.3.30.tar.gz
sudo tar -xzvf php-7.3.30.tar.gz



次に設定と必要と拡張モジュールの確認ですが、nginxほどシンプルではありません。
確認方法は以下になります。

~PHP設定/拡張モジュールの確認~

まずは必要な項目を洗い出すために、移行前のALでの「php -i」の出力結果からenabledになっている設定をリストアップします。
「./configure --help」実行すると、enabledの設定に対してconfigure実行時にどのパラメータを付与するべきか記載があるので、それを参考にします。

以下は、「BCMath」を有効にする例です。
「php -i」の結果からBCMathがenabledであることを確認したので、この設定をするパラメータを「./configure --help」で確認し、configure実行時のパラメータに付与します。

sh-4.2$ php -i
phpinfo()
PHP Version => 7.3.30

System => Linux appvisor-push-honne-stg-ap-001 4.14.209-117.337.amzn1.x86_64 #1 SMP Mon Dec 14 21:04:29 UTC 2020 x86_64
Build Date => Oct  6 2021 20:33:43
Server API => Command Line Interface
Virtual Directory Support => disabled
---省略---
Configuration	
	
bcmath	
	
BCMath support => enabled	
---省略---

ここからBCMathがenabledであることがわかったので、これを有効化するパラメータを確認。

sh-5.2$ ./configure --help
`configure' configures this package to adapt to many kinds of systems.

Usage: ./configure [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
-h, --help              display this help and exit
---省略---
--enable-bcmath         Enable bc style precision math functions
---省略---

./configure実行時に「--enable-bcmath」が必要だとわかる。
このようにして、他の設定も確認していきます。



設定の洗い出しが完了したら、必要なライブラリをインストールします。

sudo dnf install libxml2-devel openssl-devel bzip2-devel libcurl-devel readline-devel libzip-devel

展開してできたフォルダに移動してビルドします。

cd php-7.3.30
sudo ./configure --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --enable-bcmath --enable-calendar --with-curl --enable-exif  --enable-mbstring --enable-ftp --with-gettext --enable-mbstring --enable-embedded-mysqli --enable-mysqlnd --with-zlib-dir --with-openssl=/usr/local/ssl --enable-pcntl  --with-pcre-regex --with-pcre-jit --with-pdo-mysql --with-bz2 --with-readline --enable-shmop --enable-sockets --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-wddx --with-xsl --enable-zip --with-zlib --with-pear --enable-fpm --with-libxml-dir --with-mysqli --with-mysql-sock=/var/lib/mysql/mysql.sock --with-mhash --enable-dtrace
sudo make
sudo make install

phpのバージョンが確認できれば成功です。

sh-5.2$ php -v
PHP 7.3.30 (cli) (built: Dec  5 2023 02:45:23) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.30, Copyright (c) 1998-2018 Zend Technologies

php-fmp設定

次に、各種設定ファイルの配置と、phpが起動するようphp-fmpの設定を行っていきます。

ダウンロードしたPHPのソースにそれぞれ設定ファイルが含まれているので、それぞれ適切な場所に配置します。

# iniファイル
php.ini-production 
# systemd サービスファイル
sapi/fpm/php-fpm.service
# php-fpmファイル
sapi/fpm/www.conf
# php-fpm設定ファイル
sapi/fpm/php-fpm.conf
sudo mkdir -p /usr/local/php/lib/
sudo cp -p php.ini-production /usr/local/php/lib/php.ini
sudo cp -p sapi/fpm/www.conf /usr/local/etc/php-fpm.d/
sudo cp -p sapi/fpm/php-fpm.service /usr/lib/systemd/system/
sudo cp -p sapi/fpm/php-fpm.conf /usr/local/etc/

※移行前環境の設定ファイルをそのまま使用する場合は、該当ファイルを適切なディレクトリにコピーしてください。

php-fpmでphp起動するよう、設定ファイルの中身を変更します。
実行ユーザを指定し、起動用にコメントアウトの解除、パスの変更を行います。

sudo vi /usr/local/etc/php-fpm.d/www.conf

変更差分

- user = nobody
+ user = php-fpm
- group = nobody
+ group = php-fpm
sudo vi /usr/local/etc/php-fpm.conf

変更差分

- ;pid = run/php-fpm.pid
+ pid = run/php-fpm.pid
- ;daemonize = yes
+ daemonize = yes
- include=NONE/etc/php-fpm.d/*.conf
+ include=etc/php-fpm.d/*.conf

サービスを開始し、起動していれば成功です。自動起動も有効化できます。

sudo systemctl daemon-reload
sudo systemctl start php-fpm
sudo systemctl enable php-fpm
sh-5.2$ sudo systemctl status php-fpm
● php-fpm.service - The PHP FastCGI Process Manager
     Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; disabled; preset: disabled)
     Active: active (running) since Tue 2023-12-05 03:36:23 UTC; 5s ago
   Main PID: 99248 (php-fpm)
      Tasks: 3 (limit: 2257)
     Memory: 10.8M
        CPU: 41ms
     CGroup: /system.slice/php-fpm.service
             ├─99248 "php-fpm: master process (/usr/local/etc/php-fpm.conf)"
             ├─99249 "php-fpm: pool www"
             └─99250 "php-fpm: pool www"
sh-5.2$ sudo systemctl is-enabled php-fpm
enabled

実行確認

最後にnginx + PHP-FPMでPHPが実行できるか確認します。
確認方法はPHPファイルを作成してブラウザからアクセスし、実行結果が表示されれば成功です。

まずは、PHPファイルを作成します。

sudo vi /usr/share/nginx/html/index.php

以下を記載して保存します。

<?php phpinfo(); ?>

次にnginx設定ファイルを変更し、indexに作成したphpファイルを追加します。

sudo vi /etc/nginx/nginx.conf
location / {
            root   html;
-           index  index.html index.htm;
+           index  index.php index.html index.htm;
        }

以下のlocation部分のコメントアウトを外し、SCRIPT_FILENAMEのパス変更のため一部修正します。

- #location ~ \.php$ {
- #    root           html;
- #    fastcgi_pass   127.0.0.1:9000;
- #    fastcgi_index  index.php;
- #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
- #    include        fastcgi_params;
- #}
+ location ~ \.php$ {
+     root           html;
+     fastcgi_pass   127.0.0.1:9000;
+     fastcgi_index  index.php;
+     fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
+     include        fastcgi_params;
+ }

既存のindex.htmlファイルにアクセスしないよう、リネームしておきます。

sudo mv /usr/share/nginx/html/index.html /usr/share/nginx/html/index.html.backup

最後に設定ファイル反映のため、nginxを再起動します。

sudo systemctl restart nginx

ブラウザからアクセスしPHPの設定情報が表示されれば成功です。
※レスポンスがない場合、EC2のセキュリティグループ等から、任意のIPアドレスからのHTTPアクセスが許可されているかも確認ください。

まとめ

AL2023にnginxとPHPをイントールし、ブラウザから実行確認までを行いました。

今回ミドルウェアをソースからインストールすることで、普段何気なく実行しているパッケージからインストールでは、インストール以外にもユーザ、グループの作成や、systemdの登録まで自動で行ってくれていたんだなと改めて実感しました。

インストールを試みている最中はいろんなエラーに出くわし、その都度原因を特定して解決を繰り返していたので、最近あまり触れていなかったLinux OSの学習にもなり、いい勉強だったかと思います。

We're Hiring!

DELTAではチームの一員になっていただける仲間を募集中です!
下記フォームよりお気軽にご連絡ください!

https://docs.google.com/forms/d/e/1FAIpQLSfQuWNU1il5lq2rVdICM0tSK_jTsjqwc52LYEwUxBq7_ImtrQ/viewform

DELTAテックブログ

Discussion