0
0

Windows11にwsl2+Dockerで自宅Nextcloud構築

Posted at

概要

Windows11にwsl2+Dockerで自宅用Nextcloudを構築する手順です。
インターネットには公開せず、自宅LAN内での稼働を想定しています。

きっかけ

子どもが生まれ、増え続ける写真データを家族で共有する方法を探していました。
Googleフォトを有料プランにするのも、NASを購入するのも、結構お金がかかるので、自宅に転がっている機器を使って、ファイルサーバを構築すればタダじゃん楽しそうと考えたのがきっかけです。

イメージ図

自宅Nextcloud_概要-01_Overview.jpg

使用したもの

HeroBox2023 Mini PC (OS:Windows11 home)
Crucial X9 外付け SSD 1TB

1. WSL2(Ubuntu)の導入

1.1. WSL2をインストールする

管理者権限でPowerShellを起動して、以下のコマンドを実行する。
wsl --install
※--distribution:というオプションをつけると、インストールするLinuxディストリビューションを指定することが可能ですが、指定しない場合は、デフォルトのLinuxディストリビューションであるUbuntuがインストールされます。

再起動を求められたら再起動します。
WindowsにUbuntuアプリがインストールされます。
Ubuntu初回起動時にユーザ名・パスワードを入力します。

1.2. Windows起動時にWSL2が起動するようにする

・以下のバッチファイルを用意する

open-wsl.bat
wsl

・スタートアップフォルダに配置する

C:\Users\(Username)\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
※「Windowsキー+R」を押して「ファイル名を指定して実行」のダイアログボックスに「shell:startup」と入力して実行することでもスタートアップフォルダを開くことが可能。

2. USB外付けSSDのマウント

2.1. USB外付けSSDをext4にフォーマットする

私はLinuxがインストールされたノートPCが手元にあったので、それにUSB外付けSSDを接続して、mkfs.ext4コマンドでフォーマットしました。

[別の手段の候補]

・USB外付けSSDをWSL2にマウント(手順2.2.)した後に、WSL2からmkfs.ext4コマンドを実行してもできそうです。(先にe4fsprogsパッケージをインストールする必要あり)
・Windowsでもフリーソフトを使ってext4にフォーマットできそうです。

[フォーマットが必要な理由]

フォーマットせずにNextcloudを構築した場合、初めにブラウザからNextcloudを開いた画面で[インストール]ボタンを押すと、「エラー あなたのデータディレクトリは他の人が読み取ることができます ディレクトリが他人から見えないように、パーミッションを 0770 に変更してください。」と表示されます。
これは、USB外付けSSDのファイルシステムが、購入時の状態ではFAT32だったためです。パーミッションが755になっていて、FAT32はLinuxのパーミッションの概念がなくchmodすることもできません。
別の回避方法として、Nextcloudのインストール時にパーミッションのチェックをしないようにする方法もあるようですが、ここは素直にext4にフォーマットしました。

2.2. USB外付けSSDをWSL2(Ubuntu)にマウントする

・WSL2側からデバイスを見る

Ubuntuを起動してlsblkを実行

jo@herobox:~/docker-nextcloud$ lsblk
NAME MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda    8:0    0 388.6M  1 disk
sdb    8:16   0     1T  0 disk /var/lib/docker
                               /snap
                               /mnt/wslg/distro
                               /

→ディスクを認識する前の状態を確認しておく。

・Windowsで使用可能なディスクの一覧を表示する

Powershellで以下のコマンドを実行する。
GET-CimInstance -query "SELECT * from Win32_DiskDrive"

PS C:\Windows\system32> GET-CimInstance -query "SELECT * from Win32_DiskDrive"

DeviceID           Caption                              Partitions Size          Model
--------           -------                              ---------- ----          -----
\\.\PHYSICALDRIVE0 AirDisk 256GB SSD                    3          256052966400  AirDisk 256GB SSD
\\.\PHYSICALDRIVE1 Micron CT1000X9SSD9 SCSI Disk Device 1          1000202273280 Micron CT1000X9SSD9 SCSI Disk Device

→USB外付けSSDのDeviceIDとPartitionsを控えておく。
  DeviceID:\\\.\PHYSICALDRIVE1
  Partitions:1

・ディスクを認識させる

Powershellで以下のコマンドを実行
Partitionsが0の場合:wsl --mount <DiskPath>
Partitionsが1以上の場合:wsl --mount <DiskPath> --bare
※<DiskPath>は先ほど控えたDeviceID(今回は\\\.\PHYSICALDRIVE1)

PS C:\Windows\system32> wsl --mount \\.\PHYSICALDRIVE1 --bare
この操作を正しく終了しました。

・WSL2側からデバイスを見る

Ubuntuを起動してlsblkを実行

jo@herobox:~/docker-nextcloud$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda      8:0    0 388.6M  1 disk
sdb      8:16   0     1T  0 disk /var/lib/docker
                                 /snap
                                 /mnt/wslg/distro
                                 /
sdc      8:32   0 931.5G  0 disk
├─sdc1   8:33   0   128M  0 part
└─sdc2   8:34   0 931.4G  0 part

→新たにディスクが認識されたことを確認。今回マウントしたいのはsdcのパーティション番号2である。

・パーティションをマウントする

Powershellで以下のコマンドを実行
wsl --mount <DiskPath> --partition <PartitionNumber>

PS C:\Windows\system32> wsl --mount \\.\PHYSICALDRIVE1 --partition 2
ディスクは '/mnt/wsl/PHYSICALDRIVE1p2' として正常にマウントされました。
: /etc/wsl.conf  automount.root 設定を変更した場合、場所は異なります。
ディスクのマウントを解除してデタッチするには、'wsl.exe --unmount \\.\PHYSICALDRIVE1' を実行してください。

→/mnt/wsl/PHYSICALDRIVE1p2にマウントされたと出力されている。

・WSL2側からデバイスを見る

Ubuntuを起動してlsblkを実行

jo@herobox:~/docker-nextcloud$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda      8:0    0 388.6M  1 disk
sdb      8:16   0     1T  0 disk /var/lib/docker
                                 /snap
                                 /mnt/wslg/distro
                                 /
sdc      8:32   0 931.5G  0 disk
├─sdc1   8:33   0   128M  0 part
└─sdc2   8:34   0 931.4G  0 part /mnt/wsl/PHYSICALDRIVE1p2

→/mnt/wsl/PHYSICALDRIVE1p2にマウントされていることを確認。後でcompose.ymlに書くので控えておく。

・Windows起動時にマウントされるようにする

ディスクをマウントするには管理者権限が必要なため、タスクスケジューラを設定します。

  • [全般]タブ
    名前:USB外付けSSDマウント
    「ユーザーがログオンしているかどうかにかかわらず実行する」のラジオボタンをON
    「最上位の特権で実行する」のチェックをON
  • [トリガー]タブ-[新規]→
    タスクの開始:スタートアップ時
  • [操作]タブ-[新規]→
    操作:プログラムの開始
    プログラム/スクリプト:wsl
    引数の追加:--mount \.\PHYSICALDRIVE1 --partition 2

参考

3. WSL2(Ubuntu)にDocker CEをインストール

3.1. Ubuntuを起動して、以下の手順通りコマンドを実行する

参考

引用
1. Set up Docker's apt repository.

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg ##すでにインストール済みなので不要
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

2. Install the Docker packages.
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

3. Verify that the Docker Engine installation is successful by running the hello-world image.
sudo docker run hello-world

4. Dockerコンテナの作成と実行

4.1. WSL2(Ubuntu)にDocker composeをインストールする

Ubuntuを起動して、以下のコマンドを実行

jo@herobox:~$ sudo apt install docker-compose

4.2. Nextcloud用のディレクトリを作成する

jo@herobox:~$ mkdir docker-nextcloud

4.3. compose.ymlファイルを作成する

jo@herobox:~$ cd docker-nextcloud/
jo@herobox:~/docker-nextcloud$ vi compose.yml

以下の内容を記述する。

compose.yml
services:
  db:
    image: mariadb:10.6
    container_name: nextcloud_db
    restart: always
    command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
    volumes:
      - /mnt/wsl/PHYSICALDRIVE1p2/nextcloud/db:/var/lib/mysql #'/mnt/wsl/PHYSICALDRIVE1p2'の部分はWSL2にマウントしたパスを記述する。
    environment:
      MYSQL_ROOT_PASSWORD: P@ssw0rd #任意のパスワードを記述する。
      MYSQL_PASSWORD: P@ssw0rd #任意のパスワードを記述する。
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud
      TZ: Asia/Tokyo

  nextcloud:
    image: nextcloud
    container_name: nextcloud_app
    restart: always
    ports:
      - 8686:80 #他のWebアプリで8080ポートを使うつもりなので、今回は8686ポートにした。
    depends_on:
      - db
    volumes:
      - /mnt/wsl/PHYSICALDRIVE1p2/nextcloud/data:/var/www/html/data #'/mnt/wsl/PHYSICALDRIVE1p2'の部分はWSL2にマウントしたパスを記述する。
      - /mnt/wsl/PHYSICALDRIVE1p2/nextcloud/config:/var/www/html/config #'/mnt/wsl/PHYSICALDRIVE1p2'の部分はWSL2にマウントしたパスを記述する。

    environment:
      MYSQL_PASSWORD: P@ssw0rd #任意のパスワードを記述する。
      MYSQL_DATABASE: nextcloud
      MYSQL_USER: nextcloud
      MYSQL_HOST: db
      TZ: Asia/Tokyo

[補足]
volumes:の記述によって、WSL2(Ubuntu)でマウントしたUSB外付けSSDのパスを、Dockerコンテナにバインドマウントします。これにより、コンテナを削除しても写真データは消えない状態(永続化)になります。
自宅Nextcloud_概要-02_mount.jpg

4.4. コンテナを作成・起動する

jo@herobox:~$ cd docker-nextcloud/
jo@herobox:~/docker-nextcloud$ sudo docker compose up -d

4.5. コンテナができたか確認する

jo@herobox:~/docker-nextcloud$ sudo docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                                   NAMES
15fa22bb3b8a   nextcloud      "/entrypoint.sh apac…"   2 minutes ago   Up 2 minutes   0.0.0.0:8686->80/tcp, :::8686->80/tcp   nextcloud_app
5f7ed9bae989   mariadb:10.6   "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   3306/tcp                                nextcloud_db

4.6. ブラウザからnextcloudの起動を確認する

ブラウザ上で以下のアドレスを入力する。
http://localhost:8686/

4.7. Nextcloudの管理者アカウントを作成する

「管理者アカウントを作成してください」という画面が表示されているはずです。
管理者アカウントとなるユーザ名・パスワードを入力して、[インストール]ボタンを押します。
その後、推奨アプリを入れるか聞いてきますが、必要なければスキップでOK.

5. ネットワーク周りの設定

5.1. Windowsファイアウォールでポートを解放する

[コントロールパネル]-[システムとセキュリティ]-[Windows Defender ファイアウォール]-[詳細設定]-[受信の規則]
→ポート8686を解放
スクリーンショット 2024-07-27 17.32.10.png

5.2. Port Forwardingを設定する

ホストOSのIPアドレス宛ての通信をWSL2(Ubuntu)にポートフォワーディングする設定を行っていきます。

・ホストOSのIPアドレスを固定化する

192.168.0.100

・UbuntuのIPアドレスを確認する

Ubuntuを起動して、以下のコマンドを実行
ip a show dev eth0
→192.168.204.7

・ポートフォワーディングを設定する

管理者権限でPowerShellを起動して、以下のコマンドを実行する

PS C:\Windows\system32> netsh interface portproxy add v4tov4 listenaddress=* listenport=8686 connectaddress=192.168.204.7 connectport=8686

設定できたか確認する

PS C:\Windows\system32> netsh interface portproxy show all

ipv4 をリッスンする:         ipv4 に接続する:

Address         Port        Address         Port
--------------- ----------  --------------- ----------
*               8686        192.168.204.7   8686

5.3. 他端末のブラウザからNextcloudが開けるか確認する

他端末のブラウザから http://192.168.0.100:8686/ を開く

参考

6. 動画のサムネイル生成

画像のサムネイルは何もしなくても生成されるのですが、動画のサムネイル生成は一手間加える必要があります。

6.1. ffmpegをインストールする

・docker composeで立てたコンテナの中にログインする

Ubuntuを起動して、以下のコマンドを実行
docker compose exec (サービス名) /bin/bash

sudo docker compose exec nextcloud /bin/bash

・apt-get updateして、ffmpegとviをインストールする

root@15fa22bb3b8a:/var/www/html# apt-get update
root@15fa22bb3b8a:/var/www/html# apt-get install ffmpeg
root@15fa22bb3b8a:/var/www/html# apt-get install vi

・config.phpを修正する

vi config/config.php

以下を追記する

'enabledPreviewProviders' =>
  array (
    0 => 'OC\\Preview\\TXT',
    1 => 'OC\\Preview\\MarkDown',
    2 => 'OC\\Preview\\OpenDocument',
    3 => 'OC\\Preview\\PDF',
    4 => 'OC\\Preview\\MSOffice2003',
    5 => 'OC\\Preview\\MSOfficeDoc',
    6 => 'OC\\Preview\\Image',
    7 => 'OC\\Preview\\Photoshop',
    8 => 'OC\\Preview\\TIFF',
    9 => 'OC\\Preview\\SVG',
   10 => 'OC\\Preview\\Font',
   11 => 'OC\\Preview\\MP3',
   12 => 'OC\\Preview\\Movie',
   13 => 'OC\\Preview\\MKV',
   14 => 'OC\\Preview\\MP4',
   15 => 'OC\\Preview\\AVI',
 )

参考

7. バックグラウンドジョブを「Cron(推奨)」に変更

7.1. バックグラウンドジョブの設定を変更する

ブラウザでNextcloudを開き、管理者アカウントでログインし、
[管理者設定]-[基本設定]-[バックグラウンドジョブ]→「Cron(推奨)」を選択する。
→[バックグラウンドジョブ]画面に「最終ジョブ実行は xx時間前 です。何か問題が発生しています。」と表示される。

7.2. 対策を講じる

・試行1

www-data 権限 #33 でコンテナに入って、cron.phpを実行する。

jo@herobox:~/docker-nextcloud$ sudo docker compose exec -u 33 nextcloud /bin/bash
www-data@15fa22bb3b8a:~/html$ php cron.php
www-data@15fa22bb3b8a:~/html$

→直後、[バックグラウンドジョブ]画面に「最終ジョブ実行は 数秒前 です。」と表示されたので、成功したと思われる。

・試行2

WSL2(Ubuntu)からcron.phpを実行する。

jo@herobox:~/docker-nextcloud$ sudo docker compose exec -u 33 nextcloud php /var/www/html/cron.php
jo@herobox:~/docker-nextcloud$

→直後、[バックグラウンドジョブ]画面に「最終ジョブ実行は 数秒前 です。」と表示されたので、成功したと思われる。

・WSL2(Ubuntu)のrootにて、cronを設定する

cronの設定を実施

sudo crontab -e

以下を追加

*/5 * * * * cd /home/jo/docker-nextcloud && docker compose exec -u 33 nextcloud php /var/www/html/cron.php

→以降、[バックグラウンドジョブ]画面に「最終ジョブ実行は x分前 です。」と常に5分以内の時間が表示されるようになった。

参考

8. 【おまけ】バックアップ運用

ちょっと変わったバックアップの取り方をしています。
まず、バックアップ対象は、Nextcloud上に保存されたデータのみ(写真データ等)です。
もっと正確に言うと、以下の図の、My PCに同期されたデータのみをUSB外付けHDDにバックアップしています。
Nextclud自体のバックアップは取っていません。
自宅Nextcloud_概要-03_Backup.jpg

なぜこのようなバックアップ体制になっているかというと、理由は2つあります。

  1. もしハード故障などでNextcloudが動かなくなってしまっても、我が家ではそんなに困らないので、のんびり復旧or再構築するつもり。
  2. 以前からMy PCのデータをUSB外付けHDDにバックアップしていたので、運用負荷は変わらない。

メリットとしては、NextcloudとMy PCの間でデータを同期しているため、どちらかのディスクが壊れてもデータが失われない冗長構成になっている点が挙げられます。

8.1. 自動アップロード

スマホにNextcloudアプリをインストールして設定すればOK.
以下のNextcloudの公式サイトからダウンロード可能。

8.2. 自動同期

パソコンにNextcloudデスクトップクライアントをインストールして設定すればOK.
こちらも以下のNextcloudの公式サイトからダウンロード可能。

8.3. バックアップ

My PCの内蔵HDD(F:)にあるデータをUSB外付けHDD(X:)にバックアップする方法をご紹介します。
Windowsのrobocopyコマンドを以下のようにバッチファイル化して、My PCから実行しています。
src,dst,logfileの値を適宜修正すれば使い回せます。
robocopyの結果がログファイルに出力されるようにしています。出力先のフォルダはあらかじめ作っておく必要があります。

robocopy_nextcloud_F_to_X.bat
@echo off

set src="F:\Nextcloud"
set dst="X:\Nextcloud_BAK_X"
set logfile="C:\log\robocopy_nextcloud_F_to_X_%date:/=%.log"

robocopy %src% %dst% /COPYALL /E /NP /V /R:1 /W:1 /LOG+:%logfile%

rem robocopy %src% %dst% /COPYALL /MIR /NP /V /R:1 /W:1 /LOG+:%logfile%

警告
robocopyコマンドに、/MIRオプションをつけて実行する際は注意してください。
/MIRはディレクトリツリーをミラー化するオプションです。したがって、コピー元に存在しないディレクトリ及びファイルは、コピー先から削除されます。
万が一、コピー元やコピー先のパスを間違えていた場合、必要なデータが削除されてしまう可能性があります。

繰り返しますが、/MIRオプションは非常に危険です。これからバックアップを取ろうという時に、誤ってデータを削除してしまっては絶望するしかありません。
そこで、初めてrobocopyを実行する時は/MIRをつけずに、代わりに/Eをつけて実行するのが安全です。そうすることで、コピー元からコピー先へのコピーは行われますが、コピー先からデータが削除されることはありません。
上記のバッチファイル例では、/MIRをつけたコマンドの行をremでコメントアウトしてあります。
1度目は/Eで実行し、コピー元とコピー先が間違っていないことを確認した後、2度目以降は/MIRで実行すると良いでしょう。

その他のオプションの説明については、Microsoftのドキュメントをご参照ください。

以上

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0