Asusのルーターに繋がれたRaspberry Pi5に写真と動画を保存する

###  きっかけ
こどもが生まれて写真と動画を撮りまくっていたら、あっという間にクラウドが容量オーバーになりました。写真や動画を消すことがないとすると、課金が増える一方なので、いっそのことオンプレミスでサーバーを立てることにしました。
### ゴール
1. Raspberry Pi5に、DockerでNextCloudをインストール
1. Apache2.4のリバースプロキシを利用して、サブディレクトリnextcloud以下で公開
1. バックアップを設定

### ハードウェア＆OS
|  | |
|:-----------|------------:|
| ルーター| ASUS RT-AX59U|
| ラズパイ| Raspberry Pi5|
| Nvme HAT| Geekworm X1001 PCIe to M.2 Key-M|
| SSD| Team M.2 2280 NVMe PCIe Gen4x4 SSD 8TB|
| バックアップ用HDD| WDC WD80 EAZZ-00BKLB0 ×2|
| バックアップ用HDDケース | RATOC RS-EC32-U31RZ|
| OSイメージを作成するため(あると便利)|M.2 NVME SSD-USBケース|
| OS| Debian BookWorm 64bit|

### ルーターの設定
1. ルーターに外部からアクセスできるようにDDNSを設定します
1. Let's Encryptから無料のSSL証明書を取得します
![2024-05-28 213553.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1470818/652bbc19-129a-a9a7-ade1-678a98da3adb.png)

1. Webアクセス（特に443番ポート）をRaspberry Pi5に転送したいので、管理画面を8443にします
1. ラズパイ側でSSL証明書を利用できるように、ルーターにsshでログインできるようにします[^1]
![2024-05-28 225805.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1470818/e0616d74-8738-0084-5178-e288b28c3805.png)
1. ラズパイには固定プライベートIPが割り当てられるようDHCPに設定します
1. ルーターの管理画面、詳細設定[WAN]の[ポートフォワーディング]から設定します
   TCPの80番、TCPの443番、TCP/UDPの3478番(TALK用)、これらをDHCPに設定したIPへ飛ばします
### ラズパイの設定
1. 8TBのSSDからブートできるようにします[^2]
   1. 8TBのSSDにDebian Bookworm 64bitのイメージを作成します(私は、USBケースを使ってWindowsから作成しました)
   1. 一度Raspberry Pi5に8TBのSSDを接続して起動させておきます
   1. SDカードにインストールしたOSからRaspberry Pi5を起動しコマンドを実行
   NVME SSDがMBRディスクになっているので、GPTディスクに変換します
      ```bash
      sudo -i
      bash <(curl -s https://nvme.mcpat.com/gptconverter.sh)
      ```
   1. gpartedなどのツールでパーティションを拡張します
   ![スクリーンショット 2024-05-28 232330.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1470818/b34b3f69-edb6-aaca-fb84-8323d573b357.png)

1. ルーターからLet's Encrypt無料SSL証明書をとってきます
   (例：/root/.ssh/id_rsaがルーターにコピーしたラズパイの証明書、ルーターへのssh接続が192.168.0.1の2022番ポート、hogehoge.asuscomm.comで公開)
   ```bash
   ssh -i /root/.ssh/id_rsa -p 2022 admin@192.168.0.1 "cat /jffs/.le/hogehoge.asuscomm.com_ecc/fullchain.pem" > /etc/letsencrypt/live/hogehoge.asuscomm.com/fullchain.pem
   ssh -i /root/.ssh/id_rsa -p 2022 admin@192.168.0.1 "cat /jffs/.le/hogehoge.asuscomm.com_ecc/domain.key" >  /etc/letsencrypt/live/hogehoge.asuscomm.com/privkey.pem
   ```
   ルーターにsshログインして、証明書の場所(/jffs/.le/hogehoge.asuscomm.com_ecc)は確認したほうがよさそうです
   ついでに、cronにjob投入しておくとよいかもしれません  

1. NextCloudのインストール
   1. 公式[^3]に従って、Dockerもaptパッケージではなく、公式からとってきます

      ```bash
      curl -fsSL https://get.docker.com | sudo sh
      ```
      　
   1. NextCloudのインストール(127.0.0.1:11000を通じてReverse Proxyします)
      ```bash
      # For Linux and without a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else) already in place:
      sudo docker run \
      --init \
      --sig-proxy=false \
      --name nextcloud-aio-mastercontainer \
      --restart always \
      --publish 8080:8080 \
      --env APACHE_PORT=11000 \
      --env APACHE_IP_BINDING=127.0.0.1 \
      --volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
      --volume /var/run/docker.sock:/var/run/docker.sock:ro \
      --env NEXTCLOUD_DATADIR="/storage/ncdata" \
      nextcloud/all-in-one:latest
      ```

      データの保存先は/storage/ncdataになってます

   1. config.phpの編集
      コンテナの中だとviしか使えないので、一旦ローカルに保存
      ```bash
      sudo docker cp nextcloud-aio-nextcloud:/var/www/html/config/config.php config.php
      ```
      適当なエディタで編集
      ```php
        #'overwritehost'のあとにサブディレクトリを追加
        'overwritewebroot' => '/nextcloud',#'htaccess.RewriteBase'は変更不要だった

        #最後に追加
        'default_phone_region' => 'JP',
      ```
      必ずUIDとGIDをwww-dataにしてから、コンテナにもどす
      ```bash
      sudo chown www-data:www-data config.php
      sudo docker cp config.php nextcloud-aio-nextcloud:/var/www/html/config/config.php
      ```
1. Apache2の設定(インストールは、aptパッケージから)
   1. Reverse Proxy等に必要なモジュールの読み込み 
      ```bash
      sudo a2enmod proxy_http
      sudo a2enmod ssl
      sudo a2enmod headers
      ```
   1. NextCloudをサブディレクトリで運用する設定を/etc/apache2/sites-available/nextcloud.confに作成
      ```apache
      <VirtualHost *:443>
      ServerName hogehoge.asuscomm.com
      # SSL configuration
      SSLEngine on
      SSLProtocol +TLSv1.2 +TLSv1.3
      SSLCipherSuite HIGH:!MEDIUM:!LOW:!aNULL:!MD5:!RC4
      SSLHonorCipherOrder on
      SSLCompression off
      SSLCertificateFile /etc/letsencrypt/live/hogehoge.asuscomm.com/fullchain.pem
      SSLCertificateKeyFile /etc/letsencrypt/live/hogehoge.asuscomm.com/privkey.pem

      AllowEncodedSlashes NoDecode
      # Specific proxy and security configurations for Nextcloud
          <Location /nextcloud>
          ProxyPreserveHost On
          # Reverse proxy configuration
          ProxyPass http://localhost:11000 nocanon
          ProxyPassReverse http://localhost:11000

          RewriteRule ^/\.well-known/carddav /nextcloud/remote.php/dav [R=301,L]
          RewriteRule ^/\.well-known/caldav /nextcloud/remote.php/dav [R=301,L]
          RewriteRule ^/\.well-known/webfinger /nextcloud/index.php/.well-known/webfinger [R=301,L]
          RewriteRule ^/\.well-known/nodeinfo /nextcloud/index.php/.well-known/nodeinfo [R=301,L]
          # Security headers for Nextcloud
          Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains"
          Header always set X-Content-Type-Options nosniff
          Header always set X-Frame-Options "SAMEORIGIN"
          Header always set X-XSS-Protection "1; mode=block"
          Header always set Referrer-Policy "no-referrer-when-downgrade"
          </Location>
      </VirtualHost>

      ```
   1. Apacheのリスタート
      ```bash
      sudo a2ensite nextcloud
      sudo systemctl restart apache2
      ``` 
1. ブラウザーから、ラズパイIP:8080にアクセスして、urlをhogehoge.asuscomm.comに設定、NextCloud 29にチェックをいれる(29.0.1になって、初回ログインの不具合が解消されてます)
   BorgBackupを有効化する前に、バックアップ用の外付けHDDディスクをマウントしておきます。わが子の成長記録を保存するので、かならずRAIDを組んで冗長化しておきます。万が一のサルベージのためにも、フォーマットはNTFSかext4がおすすめです。Docker版NextCloudはpostgreがインストールされ、データベースとして利用されるようです。データベースもバックアップを取らないと/storage/ncdataのバックアップだけではリストアできません。BorgBackupはまとめてバックアップを取ってくれますが、リストアしない限り、バックアップファイルから直接、写真などは戻せないのではないかと思います。
1. talkを使うならサブディレクトリをいれる
![2024-05-29 015020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1470818/ceb761d3-9b80-1703-122d-13616e2cdb0f.png)


### 結果
iphoneやAndroidのNextCloudアプリから家族で写真を共有できるようになりました。
ラズパイのLAN接続は、Wifiではなく、1G対応ケーブルで有線接続がおすすめです。
5V5A環境では、NVMEをdtparam=pciex1_gen=3で安定的に稼働できています。
WebDav関係でセットアップに関する警告が出てますが、問題なくWebDavでファイル転送できてます。

[^1]:https://signal-flag-z.blogspot.com/2020/02/asus-ddns-ssltsl.html#google_vignette
[^2]:https://forums.raspberrypi.com/viewtopic.php?t=364768
[^3]:https://github.com/nextcloud/all-in-one#how-to-use-this