apache2(http2) on Docker

[【当研究室のシステム】](https://qiita.com/NeK/items/70f994b271b0c1a48590)
# 概要
[Apache2 on Docker + php-fpm on Docker](https://qiita.com/NeK/items/17e32812efc2a44b0b53)からもう一歩，http2化してみる．
手順は以下のとおり．

* mpm_freforkモジュールを無効化
* mpm_eventモジュールを有効化
* http2モジュールを有効化

## 前提

* apache2用Dockerfile
    * ~/Docker/www/Dockerfile
* php-fpm用Dockerfile
    * ~/Docker/php-fpm/Dockerfile
* http2までのセットのためのdocker-compose.yml
    * ~/Docker/docker-compose.yml
* その他
    * SSL/TLS接続の場合: 443ポート使用しか使わないので80ポートの分はもういいや

# 設定
## apache2
### confファイルなどの準備

```bash
mkdir -p ~/Docker/www/sites-available/
mkdir -p ~/Docker/www/conf/ssl.crt
mkdir -p ~/Docker/www/conf/ssl.key
```

`ServerAdmin`および`ServerName(FQDN)`は自分のものに合わせて設定しましょう．
中間CA証明書の名前はとりあえず`nii-hogehogehoge.cer`とする．
`server.crt`, `nii-hogehogehoge.cer`は`~/Docker/www/conf/ssl.crt/`に，`server.key`は`~/Docker/www/conf/ssl.key/`に入れておく．

```conf:~/Docker/www/sites-available/default-ssl.conf
<IfModule mod_ssl.c>
  <VirtualHost _default_:443>
    ServerAdmin webmaster@localhost
    ServerName my.domain.name.co.jp
    DocumentRoot /var/www/html

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    SSLEngine on

    SSLCertificateFile      /etc/apache2/conf/ssl.crt/server.crt
    SSLCertificateKeyFile /etc/apache2/conf/ssl.key/server.key
    SSLCertificateChainFile /etc/apache2/conf/ssl.crt/nii-hogehogehoge.cer
    <FilesMatch "\.(cgi|shtml|phtml|php)$">
      SetHandler "proxy:unix:/var/run/php-fpm/php-fpm.sock|fcgi://localhost"
      SSLOptions +StdEnvVars
    </FilesMatch>
    <Directory /usr/lib/cgi-bin>
      SSLOptions +StdEnvVars
    </Directory>
  </VirtualHost>
</IfModule>
```

### Dockerfileの準備

```Dockerfile:~/Docker/www/Dockerfile
FROM ubuntu:22.04

RUN set -x && \
    apt update && apt upgrade -y && \
    DEBIAN_FRONTEND=noninteractive apt install -y \
       apache2 \
       locales && \
    locale-gen ja_JP.UTF-8

ENV TZ=Asia/Tokyo LANG=ja_JP.UTF-8 LANGUAGE=ja_JP:ja

COPY ./conf /etc/apache2/conf
COPY ./sites-available /etc/apache2/sites-available

ARG HOSTNAME=www # ホスト名として名前を適宜設定(ここではwww)

# 以下ではdefault.confもdefault-ssl.confも使用する設定
RUN echo ServerName $HOSTNAME > /etc/apache2/conf-available/fqdn.conf && \
    /usr/sbin/a2enconf fqdn && \
    /usr/sbin/a2dismod php8.1 && \
    /usr/sbin/a2dismod mpm_prefork && \
    /usr/sbin/a2enmod mpm_event && \
    /usr/sbin/a2enmod proxy_fcgi && \
    /usr/sbin/a2enmod setenvif && \
    /usr/sbin/a2enmod http2 && \
    /usr/sbin/a2dissite 000-default && \
    /usr/sbin/a2ensite default-ssl && \
    /usr/sbin/a2enmod ssl && \
    /usr/sbin/a2enmod authnz_ldap && \
    /usr/sbin/a2enmod rewrite

EXPOSE 80
EXPOSE 443

CMD ["apachectl","-D","FOREGROUND"]
```

## php-fpm
### Dockerfileの準備

```Dockerfile:~/Docker/php-fpm/Dockerfile
FROM php:8.1.18-fpm-bullseye

RUN set -x && \
    curl -sSLf \
        -o /usr/local/bin/install-php-extensions \
        https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions && \
    chmod +x /usr/local/bin/install-php-extensions && \
    install-php-extensions curl

ENV TZ=Asia/Tokyo

# Use the default production configuration
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && \
    sed -i 's/memory_limit = 128M/memory_limit = -1/' "$PHP_INI_DIR/php.ini" && \
    sed -i 's/post_max_size = 8M/post_max_size = 20480M/' "$PHP_INI_DIR/php.ini" && \
    sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 20480M/' "$PHP_INI_DIR/php.ini" && \
    sed -i 's/max_execution_time = 30/max_execution_time = 600/' "$PHP_INI_DIR/php.ini" && \
    sed -i 's/;max_input_vars = 1000/max_input_vars = 5000/' "$PHP_INI_DIR/php.ini" && \
    cp /usr/local/etc/php-fpm.d/www.conf /usr/local/etc/php-fpm.d/zzz-www.conf && \
    sed -i 's!pm.max_children = 5!pm.max_children = 10!' /usr/local/etc/php-fpm.d/zzz-www.conf && \
    sed -i 's!listen = 127.0.0.1:9000!listen = /var/run/php-fpm/php-fpm.sock!' /usr/local/etc/php-fpm.d/zzz-www.conf && \
    sed -i 's!;listen.owner = www-data!listen.owner = www-data!' /usr/local/etc/php-fpm.d/zzz-www.conf && \
    sed -i 's!;listen.mode = 0660!listen.mode = 0660!' /usr/local/etc/php-fpm.d/zzz-www.conf
```

## docker-compose.yml
apache2, php-fpmを起動するdocker-compose.ymlを`~/Docker`に作成．
apache2の内容は，nfs経由でマウントする．

```yml:~/Docker/docker-compose.yml
version: '3.9'

services:
  www:
    build: ./www
    image: nek/www:latest
    container_name: www
    hostname: www
    ports:
      - 443:443
    restart: always
    depends_on:
      - php-fpm
    volumes:
      - www_data:/var/www
      - socket:/var/run/php-fpm

  php-fpm:
    build: ./php-fpm
    image: nek/php-fpm:latest
    container_name: php-fpm
    hostname: php-fpm
    restart: always
    volumes:
      - www_data:/var/www
      - socket:/var/run/php-fpm
      - /etc/group:/etc/group:ro
      - /etc/passwd:/etc/passwd:ro

volumes:
  socket:
  www_data:
    driver_opts:
      type: nfs
      o: "port=2049,addr=192.168.0.2,rw,nfsvers=4"
      device: ":/apache2/www"
```

# 運用
## ビルド＆起動

```bash
cd ~/Docker
docker compose up -d --build
```

## 起動

```bash
cd ~/Docker
docker compose up -d
```