AlmaLinuxでLAMPコンテナイメージをOSパッケージから自作

# はじめに
AlmaLinuxでLAMPのコンテナイメージをOSパッケージから作ってみたという記事。

# 環境

- VirtualBox 7.0 on MacOSX Sonoma
- AlmaLinux-9.2-x86_64-minimal.iso でデフォルトインストール

# 構築準備
podman と perl をインストールします。(perlは必須ではありません)
```
sudo dnf install podman perl -y
```

# 構築
## httpd + php コンテナイメージの作成
コンテナ作成用ディレクトリを作成して、そこにパッケージをインストールします。
```
mkdir -p ~/wk/httpd-php
sudo dnf --installroot ~/wk/httpd-php/ --releasever=/ install httpd httpd-tools php php-mysqlnd php-gd php-curl php-ftp php-fpm -y
```

設定ファイルなどの編集をしてコンテナイメージとしてインポート
・httpd のデフォルト文字コード設定の無効
・mod_mpm_prefork.so の有効化
・php-fpm の起動で必要なディレクトリの作成

※perlを使ってますが、エディタで編集しても良いです。
```
cd ~/wk/httpd-php
sudo perl -pi -e 's/^(AddDefaultCharset) .*$/$1 Off/' etc/httpd/conf/httpd.conf
sudo perl -pi -e 's/^(LoadModule .*)$/#$1/' etc/httpd/conf.modules.d/00-mpm.conf
sudo perl -pi -e 's/^#(LoadModule .*mod_mpm_prefork\.so)$/$1/' etc/httpd/conf.modules.d/00-mpm.conf
sudo mkdir -p run/php-fpm
sudo tar cf - . | podman import - httpd-php:v1
```

### コンテナイメージの確認
```
$ podman images
REPOSITORY           TAG         IMAGE ID      CREATED         SIZE
localhost/httpd-php  v1          2fa2df17933f  38 seconds ago  268 MB
```

### 動作確認

```
mkdir -p ~/data/www/html
echo "<?php phpinfo() ?>" > ~/data/www/html/phpinfo.php
podman run -dt --rm --name ph2ttpd -p 1080:80 -v ~/data/www/html:/var/www/html:Z localhost/httpd-php:v1 /bin/bash -c "/usr/sbin/php-fpm ; /usr/sbin/httpd -D FOREGROUND"
```

Firewallが有効な場合は、以下のコマンドを実行しておきます。
```
sudo firewall-cmd --permanent --zone=public --add-port=1080/tcp
sudo firewall-cmd --reload
```

ブラウザ等で http://<ホストOSのIPアドレス>:1080/phpinfo.php へアクセスして確認。
![PHP 8.0.27 - phpinfo() - 個人 - Microsoft​ Edge 2023_10_09 6_47_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/54340752-901c-c4eb-6f68-5bf0bacce8b7.png)

コンテナを停止します。
```
podman kill ph2ttpd
```

## mysqlコンテナイメージの作成

コンテナ作成用ディレクトリの作成と、パッケージのインストール。
```
mkdir -p ~/wk/mysql
sudo dnf --installroot ~/wk/mysql/ --releasever=/ install mysql-server -y
```

コンテナイメージとしてインポート。
```
cd ~/wk/mysql
sudo tar cf - . | podman import - mysql:v1
```

### コンテナイメージの確認
```
$ podman images
REPOSITORY           TAG         IMAGE ID      CREATED         SIZE
localhost/mysql      v1          34f4abe592c4  55 seconds ago  503 MB
localhost/httpd-php  v1          2fa2df17933f  11 minutes ago  268 MB
```

### 動作確認
```
mkdir -p ~/data/mysql
podman run -it --rm -v ~/data/mysql:/var/lib/mysql:Z localhost/mysql:v1 mysqld --initialize-insecure --user=root
podman run -dt --rm --name mysqldb -v ~/data/mysql:/var/lib/mysql:Z localhost/mysql:v1 mysqld -u root
```

exec で mysql コマンドを実行してみる。
```
$ podman exec -it mysqldb mysql -u root --skip-password
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.32 Source distribution

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> quit
Bye
```

パスワードなしが気になる場合はパスワードを設定する。
```
podman exec -it mysqldb mysqladmin password rootpassword -u root -p
```
※「Enter password:」はリターンのみ(パスワードなし)入力

コンテナを停止します。
```
podman kill mysqldb
```

# 動作確認
## コンテナを連携させて起動する

```
podman network create webdbnet
podman run -dt --rm --name ph2ttpd --network webdbnet -p 1080:80 -v ~/data/www/html:/var/www/html:Z localhost/httpd-php:v1 /bin/bash -c "/usr/sbin/php-fpm ; /usr/sbin/httpd -D FOREGROUND"
podman run -dt --rm --name mysqldb --network webdbnet -v ~/data/mysql:/var/lib/mysql:Z localhost/mysql:v1 mysqld -u root
```

### phpMyAdmin で動作確認
phpMyAdmin のインストールと設定をします。
```
cd ~/data/www/html
curl -sL -O https://files.phpmyadmin.net/phpMyAdmin/5.2.1/phpMyAdmin-5.2.1-all-languages.zip
unzip phpMyAdmin-5.2.1-all-languages.zip
rm phpMyAdmin-5.2.1-all-languages.zip
mv phpMyAdmin-5.2.1-all-languages phpMyAdmin
perl -p -e 's/localhost/mysqldb/' phpMyAdmin/config.sample.inc.php > phpMyAdmin/config.inc.php
```

接続ユーザー「dbadmin」を作成します。
```
$ podman exec -it mysqldb mysql -u root -p
Enter password: rootpassword
 :(略)
mysql> CREATE USER 'dbadmin'@'%' IDENTIFIED BY 'dbpassword';
Query OK, 0 rows affected (0.02 sec)

mysql> GRANT ALL PRIVILEGES ON *.* TO 'dbadmin'@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.01 sec)

mysql> quit
Bye
```

ブラウザで http://<ホストOSのIPアドレス>:1080/phpMyAdmin へアクセスして確認します。
ログインのユーザ名は作成した「dbadmin」を使います。
![PHP 8.0.27 - phpinfo() - 個人 - Microsoft​ Edge 2023_10_09 7_01_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/fc136186-0c8e-30b9-d52a-fd046874ae88.png)

![PHP 8.0.27 - phpinfo() - 個人 - Microsoft​ Edge 2023_10_09 7_02_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410957/75f78277-ff83-e5c7-336b-397b73821770.png)

# DBのコンテナを mariadb に入れ替える
デフォルトの文字コードをutf8mb4にしているのと、以下の2つの制限/不具合を回避する必要があったため、その設定を追加しています。

https://mariadb.com/kb/en/troubleshooting-row-size-too-large-errors-with-innodb/

https://dba.stackexchange.com/questions/323269/lc-time-names-cant-be-set-to-the-value-of-de-de

```
sudo dnf --installroot ~/wk/mariadb/ --releasever=/ install -y mariadb-server
cd ~/wk/mariadb
sudo sed -i '/^\[galera\]/a innodb_page_size=64k' etc/my.cnf.d/mariadb-server.cnf
sudo sed -i '/^\[mysqld\]/a character-set-server=utf8mb4' etc/my.cnf.d/mariadb-server.cnf
sudo sed -i '/^\[mysqld\]/a collation-server=utf8mb4_unicode_ci' etc/my.cnf.d/mariadb-server.cnf
sudo sed -i '/^\[mysqld\]/a character-set-client-handshake=FALSE' etc/my.cnf.d/mariadb-server.cnf
sudo sed -i '/^\[mariadb\]/a lc_messages_dir=/usr/share/mariadb/english' etc/my.cnf.d/mariadb-server.cnf
sudo sed -i '/^\[client\]/a default-character-set=utf8mb4' etc/my.cnf.d/client.cnf
sudo sed -i '/^\[mysql\]/a default-character-set=utf8mb4' etc/my.cnf.d/client.cnf
sudo tar cf - . | podman import - mariadb:v1
```

あとは初期化して、名前は「mysqldb」コンテナのままとして、mysqlと入れ替えて起動します。
```
mkdir ~/data/mariadb
podman run -it --rm -v ~/data/mariadb:/var/lib/mysql:Z localhost/mariadb:v1 mariadb-install-db
podman run -dt --rm --name mysqldb --network webdbnet -v ~/data/mariadb:/var/lib/mysql:Z localhost/mariadb:v1 mariadbd -u root
```

# おわりに
コンテナイメージは chroot 環境を tar でアーカイブしたものをインポートする事で自作できます。
OSのパッケージマネージャでインストール先ディレクトリが指定できれば、そこそこ簡単にOSパッケージからコンテナイメージを自作する事ができます。