ラズパイのdocker-compose環境でhttpsのwordpressを公開

家に転がっているラズパイを有効活用するために、冬休みの暇つぶしに構築。
あちこち資料が転がっていますが、現状の最適解はMariaDB + nginx + https-portalなのかな。

* 前提
    * sshでラズパイに入れる
    * ドメインを契約している、もしくはDynamicDNSでドメインを指定している
    * docker-composeをラズパイにインストール済み
    * 自宅ルータのポートマッピング(NAT設定)でラズパイのIP固定(DHCP割当が推奨らしい)と**ポート開放(80, 443)**

公開するのでラズパイのsshはED25519の公開鍵認証のみにするなり(パスワードなし)、ラズパイから他の端末が見えないようにネットワークを別にするなり、セキュリティには気を付けてください。

---
まずは、根幹のdocker-compose.ymlを作成
**xxxxxxxxx.comを自分のドメインに書き換えて下さい。**
```yml:docker-compose.yml
version: '3.8'

services:
  wordpress:
    container_name: wordpress
    image: wordpress:6-fpm-alpine
    restart: always
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: user
      WORDPRESS_DB_PASSWORD: password
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./app:/var/www/html
      - ./php.ini:/usr/local/etc/php/php.ini

  db:
    container_name: mysql
    image: linuxserver/mariadb:latest
    restart: always
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - ./db:/var/lib/mysql

  nginx:
    container_name: nginx
    image: nginx:alpine
    restart: always
    volumes:
      - ./web/conf.d:/etc/nginx/conf.d
      - ./web/log:/var/log/nginx
      - ./app:/var/www/html
    depends_on:
      - wordpress

  https-portal:
    container_name: https-portal
    image: steveltn/https-portal:1
    ports:
      - 80:80
      - 443:443
    restart: always
    volumes:
      - ./ssl_certs:/var/lib/https-portal
    environment:
      DOMAINS: 'xxxxxxxxx.com -> http://nginx:80'
      # STAGE: local
      # STAGE: staging
      STAGE: production
      CLIENT_MAX_BODY_SIZE: 64M
```
docker-compose.ymlと同じ階層にphp.iniを作成し、wordpressにアップロードするファイルサイズ上限を上げる。

```./php.ini
file_uploads = On
memory_limit = 64M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 600
```
web/conf.dのフォルダを作成してdefault.confを作成

```./web/conf.d/default.conf
server {
   listen 80;
   server_name localhost;
   client_max_body_size 64M; 

   root /var/www/html;
   index index.php;

   access_log /var/log/nginx/access.log;
   error_log /var/log/nginx/error.log;

   location / {
     try_files $uri $uri/ /index.php?$args;
   }
 
   location ~ \.php$ {
     try_files $uri =404;
     fastcgi_split_path_info ^(.+\.php)(/.+)$;
     fastcgi_pass wordpress:9000;
     fastcgi_index index.php;
     include fastcgi_params;
     fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
     fastcgi_param PATH_INFO $fastcgi_path_info;
   }
 }
```

続いて、公開するのでファイアウォールをかませて必要な通信だけに絞る。

ufwをインストール
```shell
sudo apt install ufw
```

ssh用に22番、http用に80番、https用に443番、docker用で172.18.0.0/16を設定する。
今回、docker間はすべて疎通させてますが、公式https-portalに限定して開放する方法があります。

```shell
sudo ufw allow 22
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow from 172.18.0.0/16
```
おまじない？
```shell
sudo ufw reload
```
ファイアウォール有効
```shell
sudo ufw enable
```
開けてるネットワークの確認
```shell
sudo ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22                         ALLOW IN    Anywhere                  
[ 2] 80                         ALLOW IN    Anywhere                  
[ 3] 443                        ALLOW IN    Anywhere                  
[ 4] Anywhere                   ALLOW IN    172.18.0.0/16             
[ 5] 22 (v6)                    ALLOW IN    Anywhere (v6)             
[ 6] 80 (v6)                    ALLOW IN    Anywhere (v6)             
[ 7] 443 (v6)                   ALLOW IN    Anywhere (v6)     
```

今回は不要ですが、ファイアウォールを無効化したければ
```shell
sudo ufw disable
```

docker-compose.ymlを置いてる階層で環境の起動。イメージのダウンロード込みとなるとしばらく時間がかかります。
```shell
docker-compose up -d
```
自分のドメインでWordpressに入ってみる。
https://xxxxxxxx.jp/

到達しなかったら、自宅と違うネットワーク(テザリングやVPN)で試みる。