Amazonのアソシエイトとして、ラズパイダ(raspida.com)は適格販売により収入を得ています。詳しくは当サイトの プライバシーポリシーをご覧ください。

Raspberry Pi 4で外出先からVPN接続してアクセスできる自分用クラウドのご紹介です。手段はいくつかありますが、Dockerで構築するのはサーバの知識が少なくてもなんとかなり、時間もかからず実用的です。

ファイル共有として有名なNextCloudと、トンネル通信できるWireguardを構築して、それをダイナミックDNSサービスで取得したURLアドレスから使う方法です。

これまでもラズパイダでは色々な方法で自分クラウドを試してきましたが、スマホからであれば、この手順が一番マネしやすいのかなと思いました。

ポートを開放しないとなりませんし、どなたにとっても簡単とは言いませんが、結構シンプルな印象です。

ラズパイ4+Docker(NextCloud+wireguard)+DDNSサービス(+ポート開放)

比較的に簡単とはいえ、やることは多めです。

スマホの公式Nextcloudアプリから使うことを前提にしています。

追記(2023/02/14):networksを見直し修正しました。外付けHDDをexternal_driveでマウントするためバインとマウントを変更しました。

実際の使い勝手

このNextCloudはiPhoneで利用しています。どちらかというと、iPhoneでデータを取り出す目的です。

iPhoneから保存することはあまりしません。なぜなら、iPhoneとMacを使っていればAppleのiCloudで事足りてしまうからです。

速度はあまり気にしていません。テキスト(doc、xlsx、txt、pdf)類が主体なせいか、ダウンロードしているなというレベルです。それにキャッシュしてくれるので、オフラインでもそれなりに見られます。

パソコン用にもNextcloudとWireguardソフトはあります。しかし、ネットワーク周りの設定がややこしいので今回は言及しません。スマホに限り、なるべくDockerを弄くるだけで実現させた形です。

Nextcloudではユーザーを作れますから、家族などに使ってもらうことができます。

NextCloud 側で権限管理はきちんとしなくてはならない点と、今回のケースだとWireguardを入れないとなりません。誰でもというわけにはいきませんね。

あくまでも個人ユースの使い勝手として、NextCloudのスマホアプリが使いやすいからとても気に入っています。実用的ですよ。

使用した環境とアプリケーション

NasPiケースと2.5インチHDD

今回のNextCloud用に用意したハードは、2.5インチSSDドライブ(240GB)を起動用兼データ置き場にし、外付けUSB接続HDD(1TB)を拡張データ置き場にしました。

  • 2.5インチSSDドライブ(240GB)
  • 外付けUSB接続2.5インチHDD(1TB)

ケースはNASPiとして販売されていた2.5インチSSDドライブを収納でき可変冷却ファンが付いたケースです。

組み込みキットでデスクトップPCライクに使う【Geekworm NASPi】

そして、NextCloudはDockerで構築しました。Portiner CEを入れることで他の機能も持たせることが簡単にできます。(PortinerCEは入れなくてもいい)

  • Raspberry Pi 0S Bullseye(64bit) lite
  • Docker  —MariaDB  —Wireguard  —(PortinerCE)オプション

メリットは、docker-compose.ymlだけで簡単にサーバを構築できる点です。間違ったとしても、コンテナを削除してやり直しができるのも助かります。

また、外部から手軽にNextcloudとやりとりするだけなら、本来はSSL通信させたいところですが、接続させるためにwireguardのポート(デフォルトは51820/udp)を開放するだけですから、httpsのポート443/tcpは特に気にしなくてもいいレベルだと思います。厳密には傍受できてしまっても、udpだけで、且つ暗号化されていれば大丈夫かなと。

公開するポートはWireguardのudpプロトコルだけになります。

WireguardはDDNSサービスを利用したドメインで接続します。当然ながらグローバルIPアドレスは変更してしまうので、cronで1日1回更新します。

他のPCからSSH接続して作業を進めますが、Raspberry Pi OSをlite版ではなくフル版で行えば、実機で作業できて安心です。本当はlite版の方が軽くて良いのですけど、最初は実機での作業の方が分かりやすいかも知れません。

プライベートIPアドレスの固定

プライベートIPも変わってしまうので、先ずは固定化しておきます。

少し古い記事ですが、dhcpcd.confの編集を参考にしてください。

Raspberry Pi 4のWi-Fi設定(初期設定) - ラズパイダ

この記事では、ラズパイのIPアドレスを192.168.0.111として進めます。

また、Raspberry Piのユーザー名はraspidaにしています。

外付けHDDのマウントとfstabへ追記

外付けHDDを使わないのならこの段落は飛ばしてください。

大容量のSSDドライブで済ませるなら必要ありません。Nextcloudのデータの保存場所としてUSBで接続するHDDを用意しました。(1TB)

nextcloudで使うのに、外付けドライブはext4フォーマットでなければなりません。また、パーミッション(権限)はwww-dataにしないと書き込めません。(fat32、exFAT、NTFS、smbフォーマットはファイルの権限管理できない)

これを事前にマウント設定しておきます。USBケーブルで接続後、fdiskやblkidでUUIDなどを調べておきます。

blkid -o List
sudo fdisk -l

今回は~/1tbhddというフォルダを作り、そこをマウントポイントとしました。

mkdir ~/1tbhdd

fstabにはUUIDで設定しました。

sudo nano /etc/fstab

ユーザーフォルダ直下にマウントした例

UUID=48fa2c6b-a280-4e77-96c3-702ff65c4947 /home/ユーザ名/1tbhdd ext4 defaults,noatime 0 0

一旦、再起動してからマウントさらた1tbhddにサーバから書き込めるようwww-dataの所有権と755の権限を与えておきました。777なら読み書き実行が誰でも何でもOK。

sudo chown -R www-data:www-data
sudo chmod -R 755 ~/1tbhdd
もしくは
sudo chmod -R 777 ~/1tbhdd

最後はdfコマンドで確認してみましょう。

df -Th

■Pi 5は8GBモデルがオススメ

Dockerのインストール

最終的に、NextCloud とスマホ、Wireguardとスマホは、QRコードを読み込ませるだけで連携できる点がとっても楽です。

一番時間を使ったのはdocker-compose.ymlの記述でした。

先ずはDokerのインストールとdocker-composeのインストールを済ませます。

インストールはこちら

docker-compose.ymlの作成

dockerをインストール後、再起動した状態からご説明します。

ymlファイルは、ホームディレクトリにnextcloudというフォルダ内に作成しました。~/nextcloudは自分で作成しています。他はdockerが作成してくれます。

外付けのHDDへのバインドは例の1つです。

外付けHDDは、Nextcloudから外部HDDとして読み込みができますから、この場所にバインドマウントしなくても良いです。

この例では敢えてhmtlフォルダ内にデータベース毎バインドする構成にしてみました。

/home/ユーザー名
        └─ /nextcloud
               └─ docker-compose.yml

/home/ユーザー名/1tbhdd
                 └─ /nextcloud
                       └ /html
                          ├─ /db
                          └─ /db_backup

ホームフォルダにnextcloudフォルダを作ってそこから始めます。

mkdir ~/nextcloud
sudo nano ~/nextcloud/docker-compose.yml

以後、~/nextcloud/内からコマンドを実行していきます。

docker -v
Docker version 23.0.1, build a5ee5b1

docker-compose -v
docker-compose version 1.29.2, build unknown

ん? インストールしたdocker-composeのバージョンにbuild unknownとなっていて、調べたらcompose-v2があるとな?!

ymlでnetwork記述が異なっていたり、するので、とりあえずそのまま。後方互換しているみたいだけどね。

まだ良く分からないので、今回はそのまま進めます。

GitHub

compose-spec/spec.md at main · compose-spec/compose-spec The Compose specification. Contribute to compose-spec/compose-spec development by creating an account on GitHub.

nextcloud部分

今回使用したnextcloud部分のdocker-compose.ymlです。

この後にwireguard部分を付け足して実行することになります。最後にコメントなしをまとめておきますので、コピペして実行してください。

分かる範囲で説明を残しておきます。私も未熟なので、より良い方法があればコメントください。

ユーザーフォルダの直下にnextcloudというフォルダを作って、その中にdocker-compose.ymlを作成しました。場所は適時読み替えてください。

version: '3.8'

services:
  nextcloud_db: #ここはdb:となっていてもコンテナ名があればそちらで指定できる
    image: linuxserver/mariadb:arm64v8-latest #ラズパイでも動くmariaDB
    container_name: nextcloud_db #コンテナ名1(任意)
    volumes:
      - ./db:/config #nextcloud直下に/dbを作ってもらい/configを配置
      - ./db_backup:/backup
    restart: always
    ports:
      - "3306:3306" #3306ポートはデフォルトポート
    environment:
      - PUID=1000 #IDコマンドでユーザーのIDを指定
      - PGID=1000 #IDコマンドでユーザーのグループIDを指定
      - TZ=Asia/Tokyo #タイムゾーンの指定
      - MYSQL_ROOT_PASSWORD=rootpass #MySQL管理者パスワード(任意)
      - MYSQL_DATABASE=nextcloud #MySQLデータベース名(任意)
      - MYSQL_USER=nextcloud #MySQLのユーザー名 (任意)
      - MYSQL_PASSWORD=password  #MySQLユーザーのパスワード(任意)
    networks:
      - mynet #nextcloudと接続するネットワークの指定

  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud #コンテナ名2(任意)
    restart: always
    ports:
      - "50080:80"  #httpポート80を50080としてポートマッピング
    volumes:
      - ./html:/var/www/html #nextcloud/htmlにバインドマウント
      - ~/1tbhdd:/1tbhdd #ユーザーフォルダ直下にマウントした外付けドライブを指定。後に外部ドライブとして認識させるため
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Tokyo
      - MYSQL_HOST=nextcloud_db #コンテナ名1を指定
      - MYSQL_DATABASE=nextcloud #nextcloud_db:と同じ
      - MYSQL_USER=nextcloud #nextcloud_db:と同じ
      - MYSQL_PASSWORD=password #nextcloud_db:と同じ
    depends_on:
      - nextcloud_db #コンテナ名1を指定
    networks:
      - default # Wireguardとも同一のネットワークに
      - mynet #DBとだけ接続する内部ネットワークの指定

networks:
  default:
    driver: bridge
    ipam:
      driver: default
  mynet:
    driver: bridge #ここで指定したネットワークとnextcloudとdbを同一にしたい
    internal: true #nextcloudとDB間だけのネットワーク
    ipam:
      driver: default

version: ‘3.8’

このバージョンについてCompose ファイルのバージョンとアップグレードに記載がありますが、インストールされたdockerエンジンのバージョンは23.0なので、3.8でもOKだよね?(そこまでパラメータを使っていないけど)

バージョン違いによって、色々とパラメータのオプションなどが削除や変更がされたりしているので混乱しますね。

services:

ツリー状になっている中で、services:とnetworks:が最上位階層になっています。services:以下、スペースでインデント(字下げ)しています。

中はnextcloud_db:とnextcloud:に分かれ、それぞれimageやportなどを設定していてます。

特にMYSQL_部分は似ているのでややこしい記述です。気をつけてください。

image: linuxserver/mariadb:arm64v8-latest

データベースはMariaDBを使いました。ラズパイだと上手く動かないイメージもあるようですが、こちらは大丈夫です。ただ、arm64v8とあるように、64bitOSのラズパイ4対応です。他のラズパイモデルではイメージを変更してください。

linuxserver/mariadb

volumes:

いくつかあるvolumes:は、ラズパイ側(ホスト側)とdocker内のひも付けみたいなものです。バインドマウント。

    volumes:
      - /home/raspida/1tbhdd/nextcloud/db:/config #ホスト側(ローカル)ディレクトリをバインドマウントUSBHDDの例
      - /home/raspida/1tbhdd/nextcloud/db_backup:/backup #ホスト側(ローカル)ディレクトリをバインドマウントUSBHDDの例

こうすることでラズパイ側からconfigファイルにアクセスできます。

ただ、外部ドライブとしてNextcloud側でネットワークドライブみたいに接続もできます。フォルダの一部として利用できますから、ここで指定しなくても外付けHDDは使えます。(マウントだけはしないとならない)

その場合、このvolumes欄は、ymlファイルと同じフォルダ(ここではnextcloud)直下にバインドマウントしてはどうでしょうか?

volumes:
  - ./db:/config
  - ./db_backup:/backup
  - /1tbgdd:/1tbhdd

このバインドマウントは、既にフォルダがある場合や、複数行で書く方法があることを知りました。3行になりますね。

    volumes:
      - type: bind  #バインドマウント指定
        source: ./nextcloud #ホスト側のディレクトリ
        target: /config #コンテナ内ディレクトリ

ports: - “3306:3306”

MariaDBのデフォルトポートは3306です。公開するわけではなく内部的に利用するので、このままで良いと思います。

environment:

この部分は.envファイルとしてymlの外に書き出すこともできるので、いずれそういう形にトライしてみたいですね。今回は変数にする必要性もないくらい少ないためenvironment:で良しとしています。

PUID=1000とGUID=1000というID指定はは大事だと知りました。コマンドidで分かります。

uid=1000(raspida) gid=1000(raspida) groups=1000(raspida),4(adm),20(dialout),24(cdrom),27(sudo),29(audio),44(video),46(plugdev),60(games),100(users),104(input),106(render),108(netdev),997(gpio),998(i2c),999(spi)

返ってきたuidがPUID、gidがGUIDです。

次にMySQLの情報です。yml全体で2ヶ所にあります。(nextcloud_db:とnextcloud:)4行のうち、1行目だけ異なり、あとは一緒です。

nextcloud_db:

  - MYSQL_ROOT_PASSWORD=rootpass #MySQL管理者パスワード(任意)
  - MYSQL_DATABASE=nextcloud #MySQLデータベース名(任意)
  - MYSQL_USER=nextcloud #MySQLのユーザー名 (任意)
  - MYSQL_PASSWORD=password  #MySQLユーザーのパスワード(任意)

nextcloud:

  - MYSQL_HOST=nextcloud_db #コンテナ名1を指定
  - (あとはnext_dbと同じ3行)

MySQLのホストの設定としてコンテナ名1のデータベースを指定しています。

**この形だと、後にNextcloudの新規アカウント作成だけでログインできました。データベース名指定なども必要ありません。多分、MYSQL_HOSTが入っているからだと思います。**ラクチン。

更にnextcloud:ではdepends_onを指定し、dbの方が先、そのあとにアプリであるnextcloudのコンテナが立ち上がる順序にするためです。(立ち上がり終わるのを待ってくれないらしく、あくまで順番のみ)

depends_on:
  - nextcloud_db #コンテナ名1を指定

こうすることで、停止する順番も逆にして実行してくれます。(なくてもいいかも)

Nextcloudのポートマッピング

nextcloud_dbの方は3306のままでしたが、nextcloudの方はポート80をポート50080にマッピングしました。

    ports:
      - "50080:80"  #httpポート80を50080としてポートマッピング

実際に後ほどNextcloudへWebブラウザから表示するのに、http://IPアドレス:50080として接続できます。

ポート番号について

ポート番号って何を指定すれば良いかなかなか分からないですよね。使っても構わないとはいえ、選ぶのが困るものです。

実際、1024〜49512なんて非公式登録も多いから、使っている環境で被っていなければいいハズです。

0~1023Well Known Port(System Ports)IANAにより登録されている
1024~49512Registered Port(User Ports)IANAにより登録されている
49513~65535Dynamic and Private PortIANAによる割り当てがされないポート番号

ポート番号

待ち受けているポートや使用ポート番号などは、コマンドで調べてみてはどうでしょう。

netstat -an | grep ポート番号

networks:

最後にmynetとしている接続するネットワークの指定です。ymlの最後にdriver: bridgeとしてホストとブリッジ接続させる記述です。

networks:
  mynet:  #ここで指定したネットワークと同一にしたい
    driver: bridge

dockerはdefaultとしてdocker0という仮想ブリッジを使います。通信自体はそれでいいが、ポートをマッピングするので、ブリッジにしたい。

後、wgnetと名前を変え、defaultをなくしました。

ここまでなら家庭内利用、次はWireguard

もしも家庭内Wi-Fiの中だけで使うなら、ここから先の部分は必要ありません。ymlファイルがあるディレクトリでcomposeからビルドできます。

docker-compose -up -d

エラー無くdoneという表示になったら、Webブラウザでhttp://IPアドレス:50080で繋いでください。

問題がなければ、新規にユーザー名とパスワード(12桁推奨)でログインできるハズです。

インストールボタンを押しても最初は少しばかり時間がかかるので、トイレに行ってくる程度経てばログインした状態でファイル一覧の画面が出ていると思います。

ここまでならWi-Fi内で運用できますが、外にいるスマホで接続したいなら、安全面も考慮してWireguardでVPN接続して利用します。

WireguardもDockerのコンテナで用意します。

次はWireguard

次の記事からWireguard部分です。Wireguardの追加と、スマホとの連携を書いていきます。

お待ちください。

先ずは家庭内でも使えるDockerのymlで、この記事は終わりにします。

ここまでのdocker-compose.yml

version: '3.8'

services:
  nextcloud_db:
    image: linuxserver/mariadb:arm64v8-latest
    container_name: nextcloud_db
    volumes:
      - ./db:/config
      - ./db_backup:/backup
    restart: always
    ports:
      - "3306:3306"
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Tokyo
      - MYSQL_ROOT_PASSWORD=rootpass
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=asdszrys3a6d
    networks:
      - mynet

  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud
    restart: always
    ports:
      - "50080:80"
    volumes:
      - ./html:/var/www/html
      - ~/1tbhdd:/1tbhdd
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Tokyo
      - MYSQL_HOST=nextcloud_db
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=asdszrys3a6d
    depends_on:
      - nextcloud_db
    networks:
      - default
      - mynet

networks:
  mynet:
    driver: bridge

スマホから自宅のNextcloud(ラズパイ4)へ繋ぐ ②Wireguardとしてこの記事の続きです。

この記事の続き

記事中で使用したラズパイのケースとドライブ

M.2ではなく、2.5インチSSD/HDDドライブが入る珍しいケースです。

冷却ファンもスリットも付いているのに、中身が窮屈でエアフローは良くありません。だからHDDはキツイかな。

使用した2.5SDDはこのタイプです。7mm高は取り付けに問題ありませんでした。

Crucial クルーシャル SSD 480GB BX500 SATA3 内蔵2.5インチ 7mm 3年保証 CT480BX500SSD1 [並行輸入品]

外付けのHDDは1TBを汎用ケースに入れて使いました。

Links

参考にしたサイトの方が分かりやすいかも知れませんね。

Docker ドキュメント日本語化プロジェクト — Docker-docs-ja 27.0 ドキュメント

docker-compose の bind mount を1行で書くな

RaspberryPI4をサーバーにして遊び倒す。その2 - Qiita

NextCloud with Wireguard: which ports to open to stay secure