QNAP Container Station Joplin Server 構築
「TS-h1283XU-RP」上のコンテナ(Container Station)で Joplin Server を構築します。
基本のセットアップ方法については、「QNAP QuTS hero 5 セットアップ」をご覧ください。
ページ内目次
Joplin って何?
セルフホスト可能なメモアプリです。EvernoteやOneNoteと同じようなものです。
他と違う点は、サーバーをセルフホスト可能で、データを自分のコントロール下に置けるということです。
似たようなものにObsidianがあり、最近はAIに食わせやすいと流行りですが、E2EEがセルフホストできないので除外します。
また、個人的に自由すぎるのが苦手なのもあります。
(VSCodeやChromeもそうなんですが何でもかんでもプラグイン形式で管理コスト的にしんどいです)
Joplinのセルフホストとしてはいくつか方法があるのですが、専用のJoplin Serverがあるのでそれを立ててみましょう。
Joplin Server を Container Station に設定
詳細はこちらにある通りで、このDockerイメージを動かす場合には、ユーザー情報のデータベース、その他環境変数の設定が必要になります。
何も設定しないとノート内容も添付ファイルもデータベースに保存しようとするため、別途データベースサーバーを立てたほうが良いです。
しかし、ストレージドライバーを設定して、ファイルシステムにファイルとして保存できるようにすると、データベースではメタデータのみの管理となります。
かなり負荷が低くなるはずで、少人数の使用であればデータベースサーバーを用意せずとも、SQLiteで十分なのでは?と思います。
(ただし、PostgreSQLへの移行ツールなどは提供されていないので、データベースの選定は慎重に)
今回は、 SQLite + ファイルシステムストレージ の構成で Joplin Server の構築を進めていくことにします。
大規模になると予想される場合には、PostgreSQL+ ファイルシステムストレージ の構成を視野にいれると良いでしょう。
事前準備
ノートの保存先として以下のディレクトリを作成します。
- /share/Container/joplin/db/
- /share/Container/joplin/storage/
デフォルトで生成された「/share/Container」以下、適当に「joplin」フォルダにしましたが何でもいいと思います。
コマンド例:
mkdir -p /share/Container/joplin/db/ && mkdir -p /share/Container/joplin/storage/
Dockerコンテナの設定
「Container Station」を開き、「コンテナ」タブから「探索」ボタンを押してDockerHubからjoplinを探します。
「コンテナまたはアプリケーションの作成」という画面が表示されるので、検索欄に「joplin」などと入力して「joplin/server」を探します。
「joplin/server」の右に表示される「デプロイ」ボタンを押します。
確認画面が表示されますが、joplin公式なので大丈夫でしょう。
イメージバージョンの選択画面になりますが、latestのまま進めてしまいます。
バージョンにこだわる人は指定していいと思います。
コンテナ作成の画面になるので、以下のように設定していきます。
- 名前:任意(わかりやすいもの)
- 設定・再起動ポリシー:「停止時以外」
- ネットワーク設定・露出ポート:22300/tcp(新しいポートの公開ボタンで追加する)
- ネットワーク設定・デフォルトの Web URL ポート:無効
「詳細設定」をクリックして、詳細設定に進む。
「環境」ページ
「新しい変数の追加」ボタンで以下の内容を増やす。
- 変数「APP_BASE_URL」 値「https://joplin.example.com/」(公開に使用するURL)
- 変数「APP_PORT」 値「22300」
- 変数「DB_CLIENT」 値「sqlite3」
- 変数「SQLITE_DATABASE」 値「/db/joplin.sqlite」
- 変数「STORAGE_DRIVER」 値「Type=Filesystem; Path=/storage」
メール設定も入れておきます。
- https://support.google.com/a/answer/176600?hl=ja
- https://support.google.com/mail/answer/185833?hl=ja
この辺を参考にして、アプリパスワードを作成しておきます。
- 変数「MAILER_ENABLED」 値「true」
- 変数「MAILER_HOST」 値「smtp.gmail.com」
- 変数「MAILER_PORT」 値「465」
- 変数「MAILER_SECURITY」 値「tls」( https://github.com/laurent22/joplin/blob/dev/packages/server/src/env.ts#L6 )
- 変数「MAILER_AUTH_USER」 値「no-reply@example.com」(Googleアカウントのメールアドレス)
- 変数「MAILER_AUTH_PASSWORD」 値「abcdefghijklmnop」(発行したアプリパスワード)
- 変数「MAILER_NOREPLY_NAME」 値「no-reply」(メールでの送信元の表示名)
- 変数「MAILER_NOREPLY_EMAIL」 値「no-reply@example.com」(メールでの送信元のメールアドレス)
- 変数「SUPPORT_EMAIL」 値「support@example.com」(通知メール内に表示される問い合わせメールアドレス)
- 変数「SUPPORT_NAME」 値「Support」
以下LDAP設定も入れておきます。
例として「 QNAP Container Station LLDAP Server 構築」設定済みとします。
- 変数「LDAP_1_ENABLED」 値「true」
- 変数「LDAP_1_USER_AUTO_CREATION」 値「true」
- 変数「LDAP_1_HOST」 値「ldaps://ldap.example.com:6360」
- 変数「LDAP_1_BASE_DN」 値「dc=ldap,dc=example,dc=com」
- 変数「LDAP_1_BIND_DN」 値「cn=ldap-readonly,ou=people,dc=ldap,dc=example,dc=com」
- 変数「LDAP_1_BIND_PW」 値「your_password」
- 変数「LDAP_1_MAIL_ATTRIBUTE」 値「mail」
- 変数「LDAP_1_FULLNAME_ATTRIBUTE」 値「displayName」
LDAP_1_BIND_DN の cn= で指定するリードオンリーのユーザーを作成済みとする。
(lldap_strict_readonlyグループに属したユーザー・Joplin Serverがユーザー検索に使用する・バインドDNと呼ぶ)
ただし、 v3.4.3 時点での Joplin Server では、都度LDAP認証を使用することはできず、ローカルのデータベースにユーザー情報が保存されてしまいます。
(LDAP_1_USER_AUTO_CREATION を true にしているので、LDAP情報をもとにローカルユーザーが作成される。falseだとユーザー作成ができないため動作しない)
よって、最初にログインしたときのLDAPのメール・パスワード・表示名(displayName)がSQLiteに保存され、その後LDAPサーバーには読みに行かないような挙動です。
ここの実装はLDAPサーバーを基準に使用したい場合は残念な感じですね。
「ストレージ」ページ
「ボリュームの追加」ボタン横の矢印から「マウントされたホストのパスをバインド」を選択して追加。
- ホスト「/Container/joplin/db」に対してコンテナ「/db」(SQLite保存先)
- ホスト「/Container/joplin/storage」に対してコンテナ「/storage」(データ保存先)
この設定でコンテナ内のディレクトリをファイルシステムにマッピングさせます。
設定が完了したら、実行してみましょう。
無事 Joplin Server が起動してくれば、 http://[QNAPのIPアドレス]:22300 で管理画面にアクセスできます。
管理用にadminユーザーが作成されるので以下の情報でログインしましょう。
- メールアドレス:admin@localhost
- パスワード:admin
LDAPを有効にしていても管理用ユーザーとして作成されます。
初期パスワードが弱いため、必ずログインしてパスワードを変更する必要があります。
Invalid origin と表示される場合
ブラウザでアクセスしても、
Invalid origin: http://example.com:22300
のようなメッセージが表示されるのは、URLが環境変数 APP_BASE_URL と一致していない場合に出るエラー。
- https://discourse.joplinapp.org/t/new-install-invalid-origin-error/17891/13
- https://github.com/laurent22/joplin/issues/5300
Originのチェックが入っているため、APP_BASE_URLをきちんと設定する必要があります。
Joplin の使い方
LDAP環境下でJoplin Serverを使用する場合には、まず最初に対象のユーザーでJoplin Serverにログインする必要があります。
Adminユーザー以外はログインを行わないとユーザーが作成されないためです。管理画面を開き、ログインを行っておきます。
Adminユーザーであれば、上部メニューに「Admin」が見えており、ユーザー管理が可能です。
LDAP環境でない場合は、Adminでログインして自由にユーザーを追加することが可能です。
Joplin Serverが準備できたら、Joplin(クライアント側のアプリケーション)をダウンロードしてインストールします。
Windows / macOS / Linux / iOS / Android 向けにアプリが用意されているのでユーザーとしてはありがたいです。
WebUIは管理画面だけであり、ノートの書き込みなど実際の操作をすることは出来ず、必ずクライアントソフトが必要になります。
インストールが完了したら設定をしていきましょう。
「ツール」から「オプション」を開き設定画面を開きます。
「全般」で「日付の形式」が「30/01/2017(日月年)」になっているので「2017/01/30(年月日)」に変更。
「全般」の「アプリケーション」内で「アップデートを自動的に確認する」のチェックを外しました。
これは何日もずっと起動しっぱなしにする時、メッセージボックスでアップデートウィンドウが出る音が気になるためです。
アップデートは手動で確認するようにします。
またメイン画面中の右上、地球のアイコンではスペルチェッカーが有効なのですが、自分はオフにしています。
Joplin Server との同期設定方法
先ほどと同様に、「ツール」から「オプション」を開き設定画面を開きます。
「同期」を開くと、様々な方法で同期できるようになっています。
「同期ウィザード」は有償契約するサービスプロバイダーの設定しか行えませんので、同期先を「Joplin Server (Beta)」にして手動で設定します。
(バージョン 3.4.12 時点では Beta になっているようです)
設定項目
- Joplin Server URL
- Joplin Server メールアドレス
- Joplin Server パスワード
は、先程WebUIにログインした際に使用した情報を入力します。
URLについてはWebUI中に表示されています。
「同期の設定を確認する」ボタンを押せば正常に同期できるかがチェックができます。
これで同期の設定は終了です。
ちなみに自分の環境だとNextcloud使用する同期方法と比較して、Joplin Serverを使用する同期のほうが後述する暗号化を入れていても10倍以上速度が向上しました。
Nextcloud同期だとファイルで同期することになるので、そのへんの違いでしょうか。
(今Nextcloudを動かしてるサーバーが低スペックなのもあると思います)
ノートブックを暗号化して保護する
Joplin Serverでセルフホストした際に、E2EE(エンドツーエンド暗号化)を使えるのが特徴です。
万が一、サーバー側でファイルが流出しても大丈夫なように、ノートブックをすべて暗号化して末端だけで表示できるように設定しましょう。
なお、E2EEを有効にするにはノートブックを全部一括で暗号化を行うしかありません。
そのため絶対に忘れないマスターパスワードを設定するようにしましょう。
先ほどと同様に、「ツール」から「オプション」を開き設定画面を開きます。
「同期」「暗号化」と開くと、E2EE(エンドツーエンド暗号化)の設定画面となります。
ここで「暗号化を有効にする」ボタンを押して、マスターパスワードを入力すればノートブックの暗号化処理が走ります。
ノートを暗号化して再同期をするため、しばらく待ちましょう。
同期が終われば暗号化は完了です。
サーバー側のファイルを確認すると全て暗号化されていて一切読めません。
別のマシンから同期をかけた場合、このように復号化に失敗します。
マスターパスワードが存在しないためです。
そのため、複数のマシンにJoplinをインストールして利用する場合、全部のマシンでマスターパスワードの入力の必要があります。
設定画面の「同期」「暗号化」からマスターパスワードを入力してノートを復号化できるようにしましょう。
暗号化ノートブックの共有
Joplin Server上に存在する別アカウントのメールアドレスを入力して特定のノートブックを共有することが出来ます。
自分がE2EEの暗号化を有効にしている場合、相手がE2EEを有効にしていないとノートブックを共有することができません。
E2EEの有効・無効は共有を行う全ユーザーで統一する必要があります。
E2EEを有効にした場合でも共有先のユーザーがE2EEを有効にすればノートブックの共有は問題なく動作します。
相手にこちらのマスターパスワードを教える必要もありません。
これは、マスターパスワードで直接ノートブックを暗号化しているのではなく、ノートブックごとに内部では公開鍵・秘密鍵が生成され、それで個別に暗号化されています。
その”キー”を受信者の公開鍵で暗号化して送るので、自分のマスターパスワードを共有しなくてもノートブックを共有できるようになっています。
