CTS-KB
情シス・社内IT 📚 シリーズ 5/10

Ubuntu データ共有セットアップ — rclone Google Drive + QNAP NAS + Obsidian Vault

⏱ 約 32 分で読めます
#脱Microsoft #Ubuntu #rclone #Google Drive #FUSE #systemd #QNAP #NFS #SMB #CIFS #Obsidian #AppArmor #AppImage #情シス

🎯 はじめに:この記事のスコープ

本記事はシリーズ 「脱Microsoft・OSS移行」の第 5 回 です。第 4 回のUbuntu 開発環境セットアップで開発スタックは完成しましたが、業務データの置き場所(クラウド・社内 NAS・ローカル)が整っていません。本記事では Ubuntu のデータ共有環境(Drive・NAS・ローカルの 3 層)を、Windows 時代の Drive for Desktop と同等の使い勝手まで持っていきます。

範囲含む含まない
本記事rclone 公式版 + Google Drive 自動マウント / VFS キャッシュ最適化 / QNAP NFS v4.1 / SMB 3.0 / AppArmor + Obsidian / DevContainer 認証情報の Drive 共有Microsoft 365 → Google Workspace のメール / 認証移行・OneDrive → Google Drive 一括コピー(第 6 回
前提第 4 回までの開発スタック完成、Google Workspace アカウント有効

💡 本記事の到達点: Windows と Ubuntu のどちらから起動しても 同じファイルが同じパス感覚で見える状態。~/GoogleDrive~/NAS/Projects がログイン時に自動マウントされ、開発機を複数台運用しても DevContainer の認証情報が Drive 経由で共有される。

🗂️ データ層の 3 層構造

CTS の業務 PC では、データを以下の 3 層に分けて配置しています。用途で置き場所を分けるだけで、Windows ↔ Ubuntu 間のファイルアクセスに迷わなくなります。

Ubuntu データ共有 3 層構造図(L1 クラウド層=Google Drive、L2 NAS 層=QNAP、L3 ローカル層=内蔵 SSD、Windows 11 と Ubuntu 26.04 の両 OS から各層への双方向アクセス経路)

実体Windows 側Ubuntu 側主な用途
L1 クラウド層Google Drive(cts-g.jp)G:\マイドライブ\(Drive for Desktop)~/GoogleDrive/(rclone mount)業務ドキュメント・開発設定の共有
L2 NAS 層QNAP TS-431X2(社内 LAN)ネットワークドライブ(SMB)~/NAS/<共有名>/(NFS or SMB)大容量メディア・社内共有データ
L3 ローカル層内蔵 SSDC:\...~/...一時ビルド成果物・キャッシュ・I/O 速度を求めるもの

用途別ファイル配置の指針

データ種別配置先理由
開発設定(~/.aws~/.config/gcloud 等)L1 Drive両 OS 間 + 複数 PC 間で共有(第 4 回 DevContainer の bind mount と組み合わせ)
業務ドキュメント(提案書・議事録・契約書)L1 Driveバージョン履歴・共有・全文検索
大容量メディア(動画素材・ISO・バックアップ)L2 NASクラウド容量と帯域の節約
一時ビルド成果物(node_modules / distL3 ローカルI/O 速度・容量・rclone の API 負荷回避
ソースコードGit(別リポジトリ)バージョン管理・PR ベースの共同編集
機密キー(本番環境用)L3 ローカル + 暗号化クラウドにも NAS にも置かない

💡 node_modules は Drive にも NAS にも置かないのが鉄則。ファイル数が多すぎて rclone API レート制限を即詰まらせます。同じ理由で .git 配下や Obsidian Vault も rclone マウント上は避ける(後述)。

☁️ Phase 5-1: rclone で Google Drive を自動マウント

Windows 側の Google Drive for DesktopG: ドライブ)と同じ感覚で、Ubuntu 側に ~/GoogleDrive/ をマウントするのが本フェーズのゴールです。実体はクラウド側、ローカルはキャッシュのみという「ストリーミング同期」モデルで、両 OS から同じファイルが見えます。仕組みとしてはユーザー空間のプログラムから FUSE 経由でカーネルにマウント要求を出す形です。

rclone のインストール(snap / apt の罠)

rclone は Ubuntu に 3 通りで入りますが、実用に堪えるのは公式スクリプトのみです。

方法バージョン制約推奨度
sudo snap install rclone1.73.5(新しい)サンドボックス内動作で Dolphin / DevContainer から見えない
sudo apt install rclone1.60.1(古い)VFS キャッシュの新オプションが使えない
公式スクリプト最新制約なし◎ 推奨

snap 版を選ぶと、rclone でマウントした ~/GoogleDriverclone プロセスの名前空間外(= 他のアプリ)から見えない症状にぶつかります。Dolphin で開いてもファイルが出てこない、docker run -v ~/GoogleDrive/... でマウントしても空に見える、など実害が大きいので避けます。

# 既存の snap 版があれば削除
sudo snap remove rclone 2>/dev/null

# 公式スクリプトでインストール
curl https://rclone.org/install.sh | sudo bash

# シェルキャッシュをクリア(snap から切り替え直後の必須手順)
hash -r

# 動作確認
which rclone        # /usr/bin/rclone であること
rclone version      # v1.73.5 以降を確認

⚠️ hash -r を忘れると古いパスを覚えたまま。snap 削除直後に which rclone/snap/bin/rclone と返してきたら hash -r 漏れです。

Google Drive リモート設定(共有ドライブ選択時の罠)

rclone config の対話で Google Drive リモートを定義します。

rclone config

入力項目

e/n/d/r/c/s/q> n              ← 新規リモート
name> gdrive                  ← 任意の名前(マウントコマンドで使う)
Storage> drive                ← Google Drive
client_id>                    ← 空 Enter(独自 ID は後述)
client_secret>                ← 空 Enter
scope> 1                      ← Full access(rwd)
service_account_file>         ← 空 Enter
Edit advanced config? n
Use auto config? y            ← ブラウザが自動起動 → cts-g.jp で認証 → 許可
Configure this as a Shared Drive (Team Drive)? n   ← 必ず n(理由は次項)
Keep this "gdrive" remote? y
e/n/d/r/c/s/q> q

⚠️ Shared Drive y 選択時の罠

Configure this as a Shared Drive? y を選ぶと、外部組織所有の共有ドライブ(取引先・パートナー組織が cts-g.jp ユーザーをゲスト招待しているもの。例: Partner DABE Program External Access のような名前)がデフォルトで提示されることがあります。意図せずそれを選ぶと、業務ファイルを 外部組織のドライブに書き込むことになり、情報漏洩リスクに直結します。

選択結果
Configure this as a Shared Drive? n(マイドライブ)マイドライブ直下にマウント。安全
Configure this as a Shared Drive? y + 自社共有ドライブ選択自社の共有ドライブをマウント
Configure this as a Shared Drive? y + 外部組織ドライブを誤選択外部組織にファイル書き込み(漏洩)

📌 マイドライブを使うなら必ず n を選択。共有ドライブを使う場合も、選択画面に出てくる名前を一字一句確認してから y/n を決めること。これは技術ではなく運用ルールの問題です。

設定確認

rclone listremotes
# → gdrive:

rclone lsd gdrive:
# → マイドライブ直下のフォルダ一覧が表示される

systemd ユーザーサービスで自動マウント

毎回手動で rclone mount を叩くのは現実的でないので、ログイン時に自動起動する systemd ユーザーサービスとして常駐させます。Windows 側 Drive for Desktop が常駐するのと同じ感覚を実現します。

マウントポイント作成

mkdir -p ~/GoogleDrive

サービスファイル作成

mkdir -p ~/.config/systemd/user

~/.config/systemd/user/rclone-gdrive.service

[Unit]
Description=rclone Google Drive mount
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
ExecStartPre=-/bin/fusermount -uz %h/GoogleDrive
ExecStartPre=-/bin/mkdir -p %h/GoogleDrive
ExecStart=/usr/bin/rclone mount gdrive: %h/GoogleDrive \
    --vfs-cache-mode full \
    --vfs-cache-max-size 20G \
    --vfs-cache-max-age 168h \
    --vfs-read-chunk-size 64M \
    --vfs-read-chunk-size-limit 1G \
    --dir-cache-time 1h \
    --poll-interval 1m \
    --buffer-size 256M \
    --transfers 8 \
    --tpslimit 10 \
    --log-file %h/.rclone.log \
    --log-level INFO \
    --allow-other
ExecStop=/bin/fusermount -u %h/GoogleDrive
Restart=on-failure
RestartSec=10

[Install]
WantedBy=default.target

ExecStartPre=- プレフィックスの意味

ExecStartPre=-/bin/fusermount -uz %h/GoogleDrive
ExecStartPre=-/bin/mkdir -p %h/GoogleDrive

- プレフィックスは 「このコマンドが失敗してもサービス全体を失敗扱いにしない」。これがないと:

  • 既にマウント済み → fusermount -uz は空振りで失敗 → Restart=on-failure で 10 秒後に再起動 → 次もまた失敗 → 起動ループ

- を付けることで、起動ループに入らず安定してマウントできます。

有効化

systemctl --user daemon-reload
systemctl --user enable --now rclone-gdrive.service
systemctl --user status rclone-gdrive.service

Active: active (running) と表示されれば成功。

動作確認

ls -la ~/GoogleDrive/
# → Windows 側 G:\マイドライブ\ と同じ内容が見えれば OK

書き込みテスト:

echo "Ubuntu test" > ~/GoogleDrive/ubuntu_test.txt
# → drive.google.com で即座に出現すれば双方向同期 OK
rm ~/GoogleDrive/ubuntu_test.txt

再起動後の自動マウント確認

sudo reboot
# 再ログイン後に
ls ~/GoogleDrive/
# → 自動的にマウントされていれば運用完成

⚠️ Docker / DevContainer から FUSE マウントが見えない問題(/etc/fuse.conf + --allow-other

通常の rclone mountマウントしたユーザー(一般ユーザー)のみが読み書きできる設定になります。Docker daemon は root として動作するため、ホスト側のシンボリックリンクで Drive 配下のディレクトリを参照する DevContainer は、bind mount に失敗します。

エラー例:

Error response from daemon: error while creating mount source path
'/home/<user>/Documents/<repo>': mkdir /home/<user>/Documents/<repo>: file exists

「ディレクトリ作成失敗」と表示されますが、実際は root から FUSE マウントが見えないことが原因(FUSE は呼び出しプロセスの UID を見る挙動がデフォルト)。

対処 1: /etc/fuse.confuser_allow_other を有効化
sudo sed -i 's|^#user_allow_other|user_allow_other|' /etc/fuse.conf
grep "^user_allow_other" /etc/fuse.conf
# → user_allow_other
対処 2: rclone mount--allow-other を付与

前項の systemd ユーザーサービスのファイルにはすでに --allow-other を入れてあります。手動マウント時のみ追加が必要:

rclone mount gdrive: ~/GoogleDrive \
    --daemon \
    --vfs-cache-mode writes \
    --allow-other
動作確認チェックリスト
# 1. rclone プロセスが --allow-other 付きで動作しているか
pgrep -af rclone | grep allow-other

# 2. /etc/fuse.conf
grep "^user_allow_other" /etc/fuse.conf

# 3. root から FUSE マウント内が見えるか(最終確認)
sudo ls ~/GoogleDrive/ | head

3 つ目で配下のフォルダが見えれば、Docker / DevContainer から bind mount できる状態。

VFS キャッシュ最適化(応答速度を桁違いに改善)

前項のサービスファイルにすでに最適化オプションを書き込んでありますが、なぜそれが必要かを整理します。rclone のデフォルト設定(--vfs-cache-mode writes + キャッシュ系オプションなし)で運用すると、ls のたびに API を叩きにいくため数秒待たされ、Drive 側の API レート制限に当たると数分間応答なしになります。

主要オプションの効果

オプションデフォルト推奨効果
--vfs-cache-modeoff / writesfull読み込みもキャッシュ → 同じファイルを繰り返し読む際の API 呼び出しが激減 ◎
--vfs-cache-max-sizeなし20Gキャッシュ上限。容量超過は古いものから自動削除
--vfs-cache-max-ageなし168h(1 週間)古いキャッシュを自動削除
--vfs-read-chunk-size128M64M大ファイル読み込みのチャンク単位
--vfs-read-chunk-size-limitなし1Gチャンクサイズ動的拡大の上限
--dir-cache-time5m1hディレクトリ一覧のキャッシュ時間
--poll-interval1m1mクラウド側変更検知の頻度
--buffer-size16M256M読み込みバッファ(16 倍)
--transfers48並列転送数
--tpslimitなし10API レート制限予防(重要)
--log-fileなし~/.rclone.logエラー追跡

実測の体感差

操作改善前(writes 単体)改善後(full + 最適化)
初回ファイル一覧数秒〜10 秒数秒(API 初回)
2 回目以降の ls数秒(毎回 API)約 10 ms(dir-cache)
ファイル読み込み毎回ダウンロード初回のみ、以降ローカルキャッシュ
接続切断後の復旧数分間応答なし約 10 秒で自動再接続

実測例:

$ time ls ~/GoogleDrive
claude  desktop  Documents
real    0m0.010s   # 約 10 ms

キャッシュ状態の確認

du -sh ~/.cache/rclone
ls ~/.cache/rclone/vfs/

ログ:

tail -f ~/.rclone.log

独自 OAuth Client ID + アプリ公開で「常時マウント断・1 週間失効」を根本解消

前項の VFS キャッシュ最適化を入れても、rclone デフォルトの OAuth Client ID は世界中の rclone ユーザーで共有されているため、混雑時間帯にレート制限を踏むことがあります。さらに、OAuth アプリを Testing モードのままにすると、付与したトークンが 1 週間で失効するため、「常時マウントが不安定で気付くと外れている」「Error 401: invalid authentication credentials が頻発する」という根本症状を生みます。

本節では、独自 Client ID の取得 + Audience の PUBLISH APP までセットで完了させる手順を 10 ステップで解説します。所要 15 分程度。

不安定の真因:2 つの問題の組み合わせ

状態レート制限トークン失効評価
デフォルト client_id全 rclone ユーザーで共有 → 混雑時にスロットリング共有 ID 側の挙動に依存×
自作 client_id + Testing モードCTS 専用クォータ付与から 1 週間で失効△(罠)
自作 client_id + PUBLISH APP(External)CTS 専用クォータ自動更新で安定
自作 client_id + Internal(Workspace 組織あり)CTS 専用クォータ自動更新で安定

⚠️ 「External=Google の審査が必要・100 ユーザー上限」は誤情報PUBLISH APP した時点で実用上の制約はかかりません。認証時に「このアプリは確認されていません」の警告画面が出ますが、「詳細」→「(安全ではないページ)に移動」で進めて問題なし(rclone 公式が明言)。自分専用のデスクトップアプリで限定 OAuth スコープを使うケースでは、Google の検証審査は実用上不要です。

Audience の選び方早見表

パターン公開作業アクセス可能ユーザートークン失効想定読者
External + Testing のまま不要テストユーザー登録分1 週間で失効(罠)短期検証のみ
External + PUBLISH APP必要(クリック 1 回)任意(初回のみ警告画面)自動更新で安定個人 Google アカウント運用
Internal不要同 Workspace 組織のみ自動更新で安定Workspace 組織あり(CTS 該当)

CTS は Google Workspace(Cloud Identity Free)契約があるため Internal が最短ルート。個人 Google アカウントや Workspace 未契約の読者は External + PUBLISH APP で同等の安定性を得られます。

以降、所要 15 分の 10 ステップ手順を順に展開します。

Step 1〜3: Google Cloud Console でプロジェクトと API を準備

  1. console.cloud.google.com にログイン(Drive にアクセスするアカウントと別でも可)
  2. **「プロジェクトの選択」→「新しいプロジェクト」**で rclone プロジェクトを新規作成(既存の本番 GCP プロジェクトとは分離
  3. **「有効な API とサービス」→「+ API とサービスの有効化」で「Drive」を検索し、「Google Drive API」**を有効化

Step 4: OAuth 同意画面の Audience を決める

「OAuth 同意画面」(または「Google Auth Platform」→「Branding」/「Audience」)から:

  • アプリケーション名: rclone
  • User Support Email: 自分のメールアドレス
  • Audience: Workspace 組織あり(CTS など)→ Internal / 個人 Google アカウントExternal(後で Step 8 で公開)

Step 5: スコープを 3 つ追加

**「Data Access」→「add or remove scopes」→「Manually add scopes」**に以下を貼り付け:

https://www.googleapis.com/auth/docs,https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/drive.metadata.readonly
スコープ用途
auth/docsGoogle ドキュメント等の Drive 内ネイティブ形式アクセス
auth/driveDrive 全体への読み書きアクセス
auth/drive.metadata.readonlyフォルダ階層・ファイル一覧の読み取り(一部 API が要求)

Step 6: テストユーザーに自分を追加(External のみ)

**「Audience」→「+ Add users」**で Drive にアクセスするアカウントを追加。Internal を選んだ場合は本ステップ不要

Step 7: OAuth Client ID を作成

「Overview」→「Create OAuth client」

  • Application type: Desktop app
  • Name: rclone(デフォルト可)

ダイアログに表示される Client ID と Client Secret を両方メモ。

Step 8: PUBLISH APP(External の最重要ステップ)

**「Audience」→「PUBLISH APP」**ボタンをクリック → 確認ダイアログで「Confirm」。

⚠️ 本ステップを飛ばすとトークンが 1 週間で失効 — Client ID は正常に作成済み・rclone も認証が通っているのに、運用 1 週間後に突然 Error 401 で全部止まります。「常時マウントが不安定で気付くと外れている」の 真の原因はここ。Internal を選んだ場合は本ステップ不要。

「Production」ステータスになれば成功。Google の検証審査は不要で、即座に運用可能です。

Step 9: rclone に Client ID / Secret を投入

rclone config

既存の gdrive リモートを編集(e)するか新規作成(n):

name> gdrive
Storage> drive
client_id> [Step 7 でメモした Client ID]
client_secret> [Step 7 でメモした Client Secret]
scope> 1                           # 1: drive (Full access all files)
service_account_file>              # 空 Enter

ブラウザで Google ログインを完了 → 次のプロンプトは 必ず n

Configure this as a Shared Drive (Team Drive)?
y/n> n

⚠️ Shared Drive で y を選ぶと外部組織のドライブを誤選択する事故が起きやすい(本記事末尾のリスクと対策表参照)。

Step 10: 動作確認

rclone lsd gdrive: --max-depth 1 | head
# → マイドライブ直下が見えれば認証成功
rclone about gdrive:
# → 容量情報が取得できれば API も健全

これで CTS 専用クォータ・自動トークン更新による安定運用に切り替わります。既存の systemd ユーザーサービス(前項)は再起動不要で、次回の API 呼び出しから新しい Client ID を使い始めます。

🩹 トラブルシュート — 401 トークン失効・マウントポイントビジー

実運用で踏みやすい症状と対処を整理します。

Error 401: Request had invalid authentication credentials(トークン失効)

症状: rclone プロセスは生きていてマウントポイントは見えるのに、配下のファイルアクセスで I/O error。~/.rclone.log に:

ERROR : /: Dir.Stat error: couldn't list directory: googleapi: Error 401:
Request had invalid authentication credentials. Expected OAuth 2 access token...
Reason: authError, Message: Invalid Credentials

原因:

  • 最頻出: Audience が Testing モードのまま運用していた(→ 前項「独自 OAuth Client ID」Step 8 を実施)
  • 長期間 rclone を使っていなかった(Google のセキュリティポリシーによる失効)
  • Google アカウント側でセキュリティイベント発生(パスワード変更等)
  • アプリの認可を Google アカウント側で取り消した

対処:

# 1. systemd service を停止
systemctl --user stop rclone-gdrive.service

# 2. マウントが残っていれば手動解除
fusermount -u ~/GoogleDrive 2>/dev/null

# 3. rclone の再認証(ブラウザが起動)
rclone config reconnect gdrive:

# 4. 認証成功確認
rclone lsd gdrive: --max-depth 1 | head

# 5. systemd service を再起動
systemctl --user start rclone-gdrive.service

💡 config reconnect は既存設定を維持したまま再認証するrclone config でリモートを作り直す必要はありません。Client ID / Secret はそのまま、OAuth トークンだけ再取得されます。ただし PUBLISH APP していない場合は 1 週間後にまた同じ症状が再発するので、根本対処は前項 Step 8 を実施してください。

fusermount: Device or resource busy(マウントポイントがビジー)

fusermount: /home/<user>/GoogleDrive: Device or resource busy

対処: lazy unmount を使う:

fusermount -uz ~/GoogleDrive

-z は「使用中のファイルハンドルが閉じられた後にアンマウント」する遅延解除モード。通常の -u で失敗したらこちらを使うのが定石。

rclone mount がフォアグラウンドで止まる

systemd サービスでは --daemon フラグは 不要Type=notify で管理するため)。手動実行時のみ --daemon を使用します。サービスファイルに --daemon を入れると systemd 側がプロセスを管理できなくなり挙動が壊れるので注意。

Obsidian Vault は rclone マウント上に置かない(致命的:データ消失リスクあり)

~/GoogleDrive/Obsidian/ のように Obsidian Vault を rclone マウント上に直接置く運用は、ログにエラーが連打されて実用に堪えないだけでなく、セッション切れのタイミングで書き込みが走るとデータ消失・ファイル破損に直結します

ERROR : .obsidian/workspace.json: Failed to copy: context canceled
ERROR : .obsidian/cache: Failed to copy: context canceled

原因:

動作影響
Obsidian は .obsidian/workspace.json毎秒〜数秒間隔で書き換えAPI レート制限を即詰まらせる
ファイルロック機構が rclone の VFS と相性悪いコピー途中でキャンセル多発
書き込み直後に再読み込みするフローキャッシュ整合性で衝突
OAuth トークン失効・ネットワーク断・スリープ復帰で rclone セッションが切れるObsidian が即座にアクセス不能になり、書き込み中だった Markdown / workspace.json がデータ消失・破損する
FUSE マウントポイントは Docker の bind mount 不可(仕様)Vault と同じパス配下に Dev Container の作業ディレクトリを置いていると、セッション切れで Dev Container も起動不能になる

⚠️ これは「うるさいだけのログエラー」ではなく、編集中ノートを失う事故です。実運用で発生済み。独自 OAuth Client ID + PUBLISH APP(§Phase 5-1 冒頭)でトークン失効頻度は大幅に下がりますが、ネットワーク断やサスペンド復帰で FUSE マウントが切れる可能性はゼロにできません。だからこそ Vault は FUSE 上に置かないことが原則です。FUSE と Docker の bind mount 制約の詳細は §Phase 5-5「なぜ作業ディレクトリを Drive 直下に置けないか」 を参照。

推奨構成

~/Obsidian/                       ← ローカルに Vault を置く(高速・安定)
~/GoogleDrive/<user>/Obsidian/   ← rclone sync で定期同期(バックアップのみ)

定期 sync スクリプト例:

#!/bin/bash
# ~/bin/obsidian-backup.sh
rclone sync ~/Obsidian ~/GoogleDrive/<user>/Obsidian \
  --exclude '.obsidian/workspace*' \
  --exclude '.obsidian/cache/**' \
  --exclude '.trash/**'

crontab -e で 1 時間に 1 回実行:

0 * * * * $HOME/bin/obsidian-backup.sh > /dev/null 2>&1

別の選択肢

方法月額特徴
Obsidian 公式 Sync$4 / 月エンドツーエンド暗号化・Vault 単位課金
Git 管理(GitLab / GitHub)$0プレーンテキストのバージョン管理向き、画像など大ファイルは LFS
上記の rclone sync 定期実行$0単方向バックアップのみ、複数端末同時編集は不向き

💡 複数端末で同時編集するなら Obsidian 公式 Sync が最も確実。1 台運用 + バックアップ目的なら rclone sync で十分です。Git 管理は知識ベースとしてのバージョン履歴が欲しい場合に強い。

🗄️ Phase 5-2: QNAP NAS への接続(NFS / SMB ハイブリッド)

NFS v4.1 vs SMB 3.0 の選び分け

QNAP TS-431X2 への Ubuntu からのアクセスでは、NFSSMB の両方が利用可能です。Windows と共有するフォルダは SMB、Linux 専用フォルダは NFS、というハイブリッド構成が現実解です。

項目SMB(CIFS)NFS
速度(GbE 環境)100〜200 MB/s200〜300 MB/s(GbE 上限近く)
CPU 負荷
Linux ネイティブ性
認証方式ユーザー / パスワードUID/GID ベース
Wayland + KDE 統合不安定なケースあり問題なし
Windows との共有× (Windows は別途 NFS クライアント有効化が必要)

⚠️ NFS はホストベース認証(送信元 IP で許可制御)なので、信頼できる社内 LAN 内での利用が前提。インターネット越しに NFS を使うのは絶対 NG。

速度実測(GbE / TS-431X2 / RAID5)

操作NFS v4.1SMB 3.0
Sequential Write100〜115 MB/s90〜110 MB/s
Sequential Read105〜118 MB/s95〜112 MB/s

GbE の理論上限(125 MB/s)に近づくのが NFS v4.1。10 GbE 環境では 500 MB/s 超も狙えます。

QNAP 側の NFS 設定(squash / ホスト IP 制限)

QNAP Web UI で 2 段階の設定が必要です。

NFS サービスの有効化

コントロールパネル → ネットワークとファイルサービス → Win/Mac/NFS/WebDAV → NFS サービス
  • ✅ NFS v2/v3 サービスを有効にする
  • NFS v4 サービスを有効にする(推奨:ファイアウォール通過が容易、認証も改善)

両方有効でも問題なし。クライアント側で vers=4.1 などバージョンを明示します。

共有フォルダごとに NFS アクセスを許可

コントロールパネル → 権限 → 共有フォルダ → <対象共有> → 編集 → NFS ホストアクセス
設定項目推奨値
アクセス権読み取り / 書き込み
ホスト / IP192.168.1.0/24(LAN 全体) または特定 IP
Squash オプションsquash なし(UID/GID 透過)
Anonymous GID/UID触らない
セキュリティsys(NFS v4 でも標準)

Squash の意味(参考)

Squash動作
squash なしクライアントの UID/GID をそのまま使用(推奨)
root squashroot だけ匿名にマッピング
all squash全ユーザーを匿名にマッピング(パブリック共有用途)

業務ファイルの読み書きが目的なら squash なし が最も自然です。

Ubuntu 側 /etc/fstab 設定(NFS

必要パッケージ

sudo apt install -y nfs-common

nfs-common には mount.nfs4 / showmount が含まれます。

エクスポート一覧の確認

QNAP がエクスポートしている NFS 共有を確認:

showmount -e 192.168.1.10

期待される出力例:

Export list for 192.168.1.10:
/Projects    192.168.1.0/24
/Shared      192.168.1.0/24
/Media       192.168.1.0/24
/Public      *

動作確認(手動マウント)

本番設定前に、まず手動でマウントできるか確認:

sudo mkdir -p /mnt/test
sudo mount -t nfs4 192.168.1.10:/Projects /mnt/test
ls /mnt/test
sudo umount /mnt/test

ファイル一覧が表示されれば NFS 設定 OK。失敗したら QNAP 側のホスト/IP 制限を確認。

マウントポイント作成

Google Drive と同じ階層に揃えると一貫性があります:

mkdir -p ~/NAS/{Projects,Shared,Media}

/etc/fstab エントリ

192.168.1.10:/Projects  /home/<user>/NAS/Projects  nfs4  defaults,_netdev,nofail,x-systemd.automount,x-systemd.idle-timeout=600,vers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2  0  0
192.168.1.10:/Shared       /home/<user>/NAS/Shared       nfs4  defaults,_netdev,nofail,x-systemd.automount,x-systemd.idle-timeout=600,vers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2  0  0
192.168.1.10:/Media    /home/<user>/NAS/Media    nfs4  defaults,_netdev,nofail,x-systemd.automount,x-systemd.idle-timeout=600,vers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2  0  0

主要オプションの意味

オプション意味
nfs4NFS v4 を使用
_netdevネットワーク利用可能まで待機
nofailNAS 不在でもブートを止めない(重要)
x-systemd.automountアクセス時マウント(高速ブート)
x-systemd.idle-timeout=60010 分アイドルで自動アンマウント
vers=4.1NFS v4.1 を明示(QNAP 互換性が高い)
rsize=1048576 / wsize=10485761 MB バッファ(GbE で最適)
hardサーバー応答停止時は無限再試行(soft だとデータロス risk)
timeo=600タイムアウト 60 秒(deci-seconds 単位)
retrans=2再送 2 回でメジャーエラー

⚠️ nofail を必ず付ける。これがないと NAS が一時的に不在のまま再起動した場合に、ブートプロセスがマウント待ちで止まります。リモートアクセス前提の業務 PC では致命的。

反映と動作確認

sudo systemctl daemon-reload
sudo mount -a

x-systemd.automount 使用時は アクセスして初めて実マウントされます:

ls ~/NAS/Projects/
# Dev / Admin / Staff / Tools などが表示されれば OK

automount ユニットの登録確認:

systemctl list-units --type=automount | grep NAS

SMB 接続時の ACCESS_DENIED の正体

Windows と共有するフォルダは SMB でマウントします。ここで Linux 特有のハマりが 1 つあります。

必要パッケージ

sudo apt install -y cifs-utils smbclient

共有一覧確認

smbclient -L //192.168.1.10 -U admin

SMB1 disabled は警告ではなく正しい状態

SMB1 disabled -- no workgroup available

これは警告ではなく セキュリティ的に正しい状態の通知です。WannaCry 等のランサムウェア対策で QNAP がデフォルトで SMB1 を無効化しています。SMB2 / SMB3 は使えるので、vers=3.0 を明示すれば問題ありません。

ACCESS_DENIED の正体

smbclient //192.168.1.10/Projects -U admin
# tree connect failed: NT_STATUS_ACCESS_DENIED

Windows クライアントからは普通にアクセスできるのに、Linux Samba クライアントだけ弾かれる現象。原因は QNAP 側の設定です。

コントロールパネル → ネットワークとファイルサービス → Win/Mac/NFS/WebDAV
  → Microsoft Networking → 詳細オプション
  → 「匿名ユーザーをSMB共有フォルダーにアクセスすることを制限する」

これが 「有効(厳格)」 だと、Linux Samba クライアントが内部的に試みる匿名アクセスフェーズで弾かれて ACCESS_DENIED になります。Windows クライアントは別経路で認証情報を渡すため成功してしまい、**「Windows では繋がるのに Linux だと繋がらない」**という切り分けにくい症状になります。

切り分け手順

  1. Public 共有でテスト — 匿名アクセス OK の共有を作って Linux からアクセス → 通れば「admin の SMB は OK だが匿名フェーズが弾かれている」と確定
  2. QNAP の上記設定を確認 → 「有効(厳格)」を 「無効」 に変更
  3. 再度 Linux からアクセス → 通る

📌 「無効」に変更してもセキュリティは下がらない — 各共有フォルダの権限設定(誰が読み書きできるか)はそのまま効きます。「匿名アクセス制限」は SMB プロトコルレベルの全共有横断のフィルターで、Linux クライアントの動作と相性が悪いだけ。

/etc/fstab エントリ(SMB)

//192.168.1.10/Projects /home/<user>/NAS/Projects cifs credentials=/root/.smbcredentials-qnap,uid=1000,gid=1000,iocharset=utf8,nofail,x-systemd.automount,_netdev,vers=3.0 0 0

/root/.smbcredentials-qnap(root のみ読める権限で保存):

username=admin
password=<パスワード>
sudo chmod 600 /root/.smbcredentials-qnap

NFS と SMB のハイブリッド構成

# Ubuntu 専用(NFS - 高速)
192.168.1.10:/Dev        /home/<user>/NAS/Dev   nfs4  defaults,_netdev,nofail,x-systemd.automount,vers=4.1  0 0

# Windows と共有(SMB)
//192.168.1.10/Projects /home/<user>/NAS/Projects cifs credentials=/root/.smbcredentials-qnap,uid=1000,gid=1000,nofail,x-systemd.automount,vers=3.0  0 0

両方を /etc/fstab に並べて記述すれば共存します。

NFS v4 idmap が「全員 nobody」になる場合の対処

NFS v4 でマウントしたディレクトリで ls -la すると、ファイル所有者がすべて nobody:nogroup になっているケースがあります。

ls -la ~/NAS/Projects/
# -rw-r--r-- 1 nobody nogroup ...

原因は NFS v4 の idmap ドメイン不一致。NFS v4 はデフォルトで idmapd を使い、クライアント側 / サーバー側のドメインが一致していないと全員 nobody にマッピングされます。

対処 1: idmapd ドメインを QNAP 側と合わせる

sudo nano /etc/idmapd.conf
[General]
Domain = localdomain    # QNAP 側と合わせる

QNAP 側のドメイン設定:

コントロールパネル → ネットワークとファイルサービス
  → Win/Mac/NFS/WebDAV → NFS サービス → 詳細オプション
sudo systemctl restart nfs-idmapd

対処 2: NFS v3 にフォールバック

idmap を回避してシンプルに UID/GID をそのまま使うなら、vers=4.1vers=3 に変更:

192.168.1.10:/Projects  /home/<user>/NAS/Projects  nfs  ...,vers=3,...  0 0

NFSv3 は UID/GID をそのまま渡すので、QNAP 側の UID/GID と Ubuntu 側の 1000 が揃っていれば素直に動きます。

💡 業務 NAS の運用では UID 1000 で揃えるのがシンプル。QNAP 管理画面でユーザーを作成する際、Ubuntu と同じユーザー名で UID 1000 を割り当てておけば、idmap で悩まずに済みます。

📝 Phase 5-3: Obsidian を AppArmor で安全に動かす

Ubuntu 24.04+ の AppImage 起動エラー

Obsidian は AppImage で配布されている Electron アプリですが、Ubuntu 24.04 以降では 2 つのエラーが連続して出ます。

エラー 1: libfuse がない

./Obsidian-1.12.7.AppImage
dlopen(): error loading libfuse.so.2
AppImages require FUSE to run.

Ubuntu 24.04 以降は libfuse2(deprecated)ではなく libfuse2t64(time_t 64-bit 対応版)が必要です。古い情報源は libfuse2 を案内していることが多いので注意。

sudo apt install -y libfuse2t64

エラー 2: SUID Sandbox エラー

libfuse 解決後、次に出るのが:

[FATAL:setuid_sandbox_host.cc:166] The SUID sandbox helper binary was found,
but is not configured correctly.

原因は Ubuntu 23.10 以降、kernel.apparmor_restrict_unprivileged_userns=1 がデフォルト有効化されていること。Electron 系アプリが内部で使う非特権 user namespace の作成が AppArmor で制限され、SUID sandbox にフォールバックしようとして失敗します。

解決策セキュリティ影響範囲採否
AppArmor プロファイル作成◎ 維持Obsidian のみ✅ 採用
--no-sandbox 起動✗ Electron sandbox 無効化Obsidian のみ
sysctluserns 制限解除△ システム全体緩和OS 全体
Flatpak 版に変更◎ 維持△(AppImage を選んだ場合の対案)

Obsidian の特性上、サンドボックス有効化は重要

  • コミュニティプラグインで任意の JS が実行される
  • Vault 内 Markdown が外部 URL / iframe を扱う可能性
  • Vault がローカルファイルへのアクセス権を持つ

--no-sandbox で起動するのは生産性は出ますが、プラグインの脆弱性経由でファイルシステムを舐められるリスクがあるため、AppArmor プロファイルで userns だけ許可するのが正解です。

AppArmor プロファイルで userns を許可(推奨解)

Obsidian 専用の AppArmor プロファイルを作成し、userns, だけを許可します。

sudo tee /etc/apparmor.d/obsidian > /dev/null <<'EOF'
abi <abi/4.0>,
include <tunables/global>

profile obsidian /home/*/AppImages/obsidian.appimage flags=(unconfined) {
  userns,
  include if exists <local/obsidian>
}
EOF

sudo apparmor_parser -r /etc/apparmor.d/obsidian

プロファイルの意味

役割
abi <abi/4.0>AppArmor ABI バージョン
flags=(unconfined)AppArmor 自体の制限はかけない(Electron 内部の sandbox に任せる)
userns,非特権 user namespace の作成を許可 ← これが SUID sandbox エラー解消のポイント
include if exists <local/obsidian>ローカルカスタマイズ用の include(オプション)

適用確認

sudo aa-status | grep obsidian
# → obsidian

これで Obsidian は Electron 内部の sandbox を有効化したまま起動できるようになります。プラグインの脆弱性経由のファイルシステム侵害から守られた状態。

Gear Lever で AppImage を統合管理

AppImageLauncher は廃止

長らく定番だった AppImageLauncher は公式に deprecated。Ubuntu 26.04(resolute)用の Release ファイルもなく PPA から 404 が返ります。

THIS PPA IS DEPRECATED!
See https://github.com/TheAssassin/AppImageLauncher/discussions/706
# 残存 PPA の除去
sudo add-apt-repository --remove ppa:appimagelauncher-team/stable 2>/dev/null

Gear Lever(Flatpak 版)を採用

代替として Gear Lever を採用します。GTK4 / libadwaita 製で、Ubuntu 26.04 でも素直に動作。

# Flatpak の前提(既に導入済みならスキップ)
sudo apt install -y flatpak
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo

# Gear Lever(user install)
flatpak install flathub it.mijorus.gearlever
# プロンプト: "Which do you want to use? [0-2]" → 2 (user) を選択

user install を選ぶ理由

観点system installuser install
インストール先/var/lib/flatpak/~/.local/share/flatpak/
必要権限sudoユーザー権限のみ
影響範囲全ユーザー自分のみ
dotfile 管理◎ 復元可能

業務 PC は実質 1 ユーザー運用なので、dotfile 管理しやすい user install が筋。

AppImage 配置と統合

Gear Lever で Obsidian の AppImage を取り込むと、自動的に:

  • ~/AppImages/obsidian.appimage に正規化
  • アイコンを ~/AppImages/.icons/obsidian に展開
  • ~/.local/share/applications/obsidian.desktop を生成

ただし自動生成された .desktop には --no-sandbox が含まれているため、sed で除去します。

sed -i 's| --no-sandbox||' ~/.local/share/applications/obsidian.desktop
update-desktop-database ~/.local/share/applications/

アップデート後の --no-sandbox 復活対策

Gear Lever 経由でアップデートすると .desktop が再生成され、--no-sandbox が復活する可能性があります。エイリアスにしておくとワンコマンドで復旧:

echo "alias fix-obsidian-sandbox='sed -i \"s| --no-sandbox||\" ~/.local/share/applications/obsidian.desktop && update-desktop-database ~/.local/share/applications/'" >> ~/.bashrc

動作検証

~/AppImages/obsidian.appimage

期待されるログ:

Loaded main app package /tmp/.mount_obsidiwoarcT/resources/obsidian.asar
Checking for update using Github
Success.
App is up to date.

サンドボックスエラーが出ない = AppArmor プロファイル + userns 許可が機能している証拠。

同パターンを Cursor / Insomnia / Postman に横展開

同じ userns, 許可パターンが、Electron 系 AppImage 全般に適用できます。

アプリ用途プロファイル名
CursorAI 統合エディタ(VS Code フォーク)/etc/apparmor.d/cursor
InsomniaAPI テスト/etc/apparmor.d/insomnia
PostmanAPI テスト/etc/apparmor.d/postman
VS Code AppImage 配布版エディタ/etc/apparmor.d/vscode

例: Cursor 用:

sudo tee /etc/apparmor.d/cursor > /dev/null <<'EOF'
abi <abi/4.0>,
include <tunables/global>

profile cursor /home/*/AppImages/cursor.appimage flags=(unconfined) {
  userns,
  include if exists <local/cursor>
}
EOF
sudo apparmor_parser -r /etc/apparmor.d/cursor

💡 /home/*/AppImages/<name>.appimage のパスパターンを統一しておくと、複数 PC・複数ユーザーで同じプロファイルが使い回せます。Gear Lever はこのパスに正規化してくれるため相性が良い。

🔁 Phase 5-4: DevContainer 認証情報の Drive 経由共有(応用)

第 4 回 Ubuntu 開発環境セットアップ の DevContainer は、~/.aws ~/.config/gcloud ~/.gitconfig ~/.ssh ~/.claude などホスト側の認証情報を bind mount で持ち込む設計でした。複数の Ubuntu 開発機(自宅 + オフィス、デスクトップ + ノート)を運用するなら、この設定一式を Drive 経由で共有できます。

運用パターン

~/GoogleDrive/<user>/dotfiles/      ← 認証情報のマスター
  ├── .aws/
  ├── .config/gcloud/
  ├── .gitconfig
  └── .claude/   (セッショントークン込み)

~/.aws → ~/GoogleDrive/<user>/dotfiles/.aws        (シンボリックリンク)
~/.gitconfig → ~/GoogleDrive/<user>/dotfiles/.gitconfig
~/.claude → ~/GoogleDrive/<user>/dotfiles/.claude
ln -s ~/GoogleDrive/<user>/dotfiles/.aws ~/.aws
ln -s ~/GoogleDrive/<user>/dotfiles/.gitconfig ~/.gitconfig
ln -s ~/GoogleDrive/<user>/dotfiles/.claude ~/.claude

メリット

  • どの PC からも同じ AWS / GCP / GitLab / Claude Code セッションで作業できる
  • 複数 PC 間で ~/.claude のセッショントークンが揃う → 再認証不要
  • DevContainer の bind mount は ~/.aws を見るので、シンボリックリンクは透過

注意点

項目留意事項
秘密鍵(~/.ssh/id_*Drive 経由共有は避ける。各 PC で個別に生成し、公開鍵だけ GitLab / GitHub に登録
本番環境のクレデンシャルDrive に置かない。~/.aws/credentials の本番用プロファイルは別管理
~/.claude の rclone マウント上配置OK。書き込み頻度は Obsidian Vault ほど高くない
退職時の対応Drive 共有を解除すれば全 PC から一括失効可能(Workspace 管理コンソール経由)

💡 **「秘密鍵は各 PC ローカル / 認証トークン・設定は Drive」**の使い分けが現実解。Workspace 側で MFA + デバイス管理を効かせれば、Drive のクレデンシャル流出リスクは管理可能なレベルまで下がります。

🔄 Phase 5-5: ローカル ↔ Drive 双方向同期(rclone bisync + cron 自動同期)

Phase 5-4 で扱った「Drive 経由で共有してよい / よくない」の線引きでは、**DevContainer の作業ディレクトリ(リポジトリのソースコード等)**は判断保留にしていました。本フェーズでその答えを出します。

なぜ作業ディレクトリを Drive 直下に置けないか — Docker bind mount は FUSE 上を bind できない

Docker(FUSE 仕様の制約)は、rclone の FUSE マウントポイント上のパスを bind mount できません~/GoogleDrive/.../<repo>source に指定した devcontainer.json で Dev Container を起動しようとすると、bind mount が失敗してコンテナ自体が起動しない、もしくは rclone のセッションが切れた瞬間に Dev Container が応答不能になります。

そこで以下の構成を採用します:

役割配置先参照する側
Dev Container の作業ディレクトリローカル ~/Documents/<repo>Dev Container(bind mount)
同一リポジトリの Drive コピー~/GoogleDrive/<user>/.../<repo>(rclone マウント上)Obsidian / Windows / iPhone(Drive 直接参照)
ローカル ↔ Drive 同期rclone bisync を cron で 5 分ごと

ローカル ↔ Drive 双方向同期アーキテクチャ図(Dev Container はローカル bind mount、ローカルと Google Drive を cron bisync で 5 分ごと双方向同期、Drive 側を Obsidian と他デバイスが参照)

ローカルが「正本」、Drive は「他デバイスへの配布チャネル + バックアップ」という分担です。

devcontainer.json のマウント設定

.devcontainer/devcontainer.jsonmounts または source 指定で、Drive 上のパスではなく ローカルパス を渡します:

{
  // ...
  "workspaceMount": "source=${localEnv:HOME}/Documents/<repo>,target=/home/vscode/Documents/<repo>,type=bind"
}

⚠️ source にホスト側 ~/GoogleDrive/... を書かない — FUSE 上のパスは bind mount できません。必ずローカル ~/Documents/... を指定します。

初回セットアップ

# 1. ローカルフォルダを作成
mkdir -p ~/Documents/<repo>

# 2. Drive からローカルへ初回コピー(既に Drive 側にデータがある場合)
rclone copy gdrive:<user>/path/to/<repo> ~/Documents/<repo>

# 3. bisync を初期化(両方の現在の状態を基準点として記録)
rclone bisync /home/<user>/Documents/<repo> gdrive:<user>/path/to/<repo> --resync

⚠️ --resync は初回実行で必須 — bisync は両側の前回状態をリスティングファイル(~/.cache/rclone/bisync/)として記録し、それを基準に差分同期します。--resync なしで初回実行するとエラーで停止(後述のトラブルシュート参照)。

cron で定期同期(5 分ごと)

crontab -e

以下の行を追加:

*/5 * * * * /usr/bin/rclone bisync /home/<user>/Documents/<repo> gdrive:<user>/path/to/<repo>

💡 cron 環境の注意点:

  • ~ が展開されないことがあるため、必ず /home/<user>/... のフルパスを書く
  • rclone/usr/bin/rclone でフルパス指定(cron の PATH は最小限)

設定確認:

crontab -l

手動同期(即時反映したい場合)

rclone bisync /home/<user>/Documents/<repo> gdrive:<user>/path/to/<repo> --verbose

--verbose で何を同期しているかが見えるので、初回数回は手動で実行して挙動を確かめてから cron 化するのが安全です。

bisync エラーからの復旧

以下のエラーで bisync が停止することがあります:

ERROR : Bisync critical error: cannot find prior Path1 or Path2 listings
ERROR : Bisync aborted. Must run --resync to recover.

原因: リスティングファイル(前回状態の基準点)が破損したか、片側で大量の変更があって差分判定が困難になった状態。

対処: --resync で基準点を再作成します:

rclone bisync /home/<user>/Documents/<repo> gdrive:<user>/path/to/<repo> --resync

💡 --resync は両側の現在状態をそのまま受け入れるため、片方で消したファイルが復活したり、競合した編集の一方が上書きされる可能性があります。事故時のリカバリ前に 両側の git status / Drive 上のタイムスタンプを確認してから実行してください。

🛡️ リスクと対策表

リスク影響度対策
rclone config で Shared Drive y を選び外部組織のドライブを誤選択致命的(情報漏洩)マイドライブを使うなら必ず n。共有ドライブを使うときは表示名を一字一句確認
ExecStartPre のコマンド失敗で systemd が起動ループ- プレフィックスで失敗を無視(ExecStartPre=-/bin/fusermount -uz ...
デフォルト設定(writes のみ)で API レート制限を踏む--vfs-cache-mode full + --tpslimit 10 + 独自 OAuth Client ID
OAuth アプリを Testing モードのまま放置 → 1 週間でトークン失効・常時マウント断中(最頻出)Audience を Internal(Google Workspace 組織あり)にするか、External なら PUBLISH APP を実行(§「独自 OAuth Client ID」Step 8 参照)
Docker / DevContainer から FUSE マウントが見えず bind mount 失敗中(Linux ホスト固有)/etc/fuse.confuser_allow_other を有効化 + rclone mount--allow-other を付与(§「systemd ユーザーサービスで自動マウント」サブセクション参照)
systemd サービスファイルに --daemon を入れて起動不能Type=notify 管理時は --daemon 不要。手動マウント時のみ使用
rclone bisync 初回実行で --resync 忘れ → cannot find prior Path1 or Path2 listings で停止中(実体験)初回は必ず rclone bisync ... --resync で基準点を作成。同エラーが運用中に出た場合も --resync で再作成(§Phase 5-5 参照)
cron~ 不展開で rclone bisync が静かに失敗crontab には フルパス/home/<user>/Documents/<repo>/usr/bin/rclone を書く
Obsidian Vault を rclone マウント上に配置 → 同期エラー連発Vault はローカル ~/Obsidian/、rclone sync で定期バックアップ
QNAP 匿名制限「厳格」で Linux SMB が ACCESS_DENIEDQNAP の Microsoft Networking 詳細で「無効」に変更
NFS v4 idmap ドメイン不一致で全員 nobody:nogroup/etc/idmapd.confDomain を QNAP 側と合わせる、または vers=3
nofail 忘れで NAS 不在時にブートが止まる/etc/fstab に必ず nofail,x-systemd.automount
Obsidian の --no-sandbox 起動でプラグイン経由のファイル侵害AppArmor プロファイルで userns, 許可 + .desktop から --no-sandbox 除去
アップデートで --no-sandbox 復活fix-obsidian-sandbox エイリアスで復旧
秘密鍵(~/.ssh/id_*)を Drive 共有して漏洩致命的秘密鍵は各 PC でローカル生成。Drive には公開鍵すら共有しない
ローカルバックアップが Drive 上の node_modules で詰まるnode_modules .git Vault は ローカル運用、Drive には置かない

✅ 第 5 回まとめ

データ層フェーズで押さえるべき項目チェックリスト:

  • rclone は公式インストールスクリプトで導入。snap 版(サンドボックス制約)/ apt 版(古い)は避ける
  • rclone config の Shared Drive 選択は必ず n(マイドライブ運用)。y を選ぶと外部組織のドライブを誤選択するリスクあり
  • systemd ユーザーサービスで自動マウントExecStartPre=- で起動ループ防止
  • VFS キャッシュは --vfs-cache-mode full + --tpslimit 10 + --buffer-size 256M で 2 回目以降の ls約 10 ms
  • 独自 OAuth Client ID(GCP プロジェクト → Drive API → デスクトップアプリ)でレート制限を根本解消(10 分作業)
  • Obsidian Vault は rclone マウント上に置かない。ローカルに置いて rclone sync で定期バックアップ
  • QNAP は NFS v4.1(高速)/ SMB 3.0(Windows 共有)のハイブリッド/etc/fstab + nofail,x-systemd.automount,vers=4.1 必須
  • QNAP 匿名制限「厳格」が Linux SMB の ACCESS_DENIED の正体。「無効」に変更
  • NFS v4 で全員 nobody になったら /etc/idmapd.confDomain を QNAP と揃えるか vers=3 にフォールバック
  • Obsidian / Cursor / Insomnia / Postman など Electron AppImage は AppArmor プロファイルで userns, 許可--no-sandbox で逃げない
  • Gear Lever(Flatpak user install)で AppImage 統合管理。AppImageLauncher は廃止
  • DevContainer 認証情報を Drive 共有するなら、秘密鍵は各 PC ローカル、設定とトークンだけを共有

これで OS の土台 + 業務 PC 化 + 開発スタック + データ層 までが完成しました。次回からはコラボレーション・本番移行のフェーズに入ります。

次回(公開済み)「Microsoft 365 → Google Workspace 全面移行」では、メール・SSO・MFA・MX 切替に加えて、本記事で構築した rclone マウント基盤を使った OneDrive → Google Drive ファイル移行(差分同期・共有リンク棚卸し) までを、ドメイン移行のダウンタイムを最小化する手順で解説します。

📚 シリーズ記事

#タイトル内容
1脱Microsoft 全体戦略・総論値上げ背景・ロードマップ・コスト・リスク
2Windows 11 + Ubuntu デュアルブート構築M.2 物理分離・KDE Plasma・GRUB
3Ubuntu PC セットアップNVIDIA ドライバ事後導入・サスペンド無効化・Bluetooth・ターミナル選定
4Ubuntu 開発環境セットアップDocker Engine ネイティブ・DevContainer 機密情報マウント・Claude Code
5Ubuntu データ共有セットアップ(本記事)rclone Drive + systemd・QNAP NFS/SMB・Obsidian Vault・AppArmor
6Microsoft 365 → Google Workspace 全面移行メール・SSO・MFA・MX 切替 + OneDrive → Google Drive ファイル移行・共有リンク・コスト最適化
7Ubuntu リモート開発セットアップTailscale + SSH + VS Code Remote / DevContainer・Wayland ホスト
8ActiveReports → Playwright + Scriban 移行(公開予定)帳票エンジン置換・バーコード・印刷品質 PDF
9コスト削減効果と 1 年運用レビュー(公開予定)実績ベースのコスト・運用上のハマりどころ

🔗 関連リソース

CTS-KB 内の関連記事

関連用語

  • rclone — クラウドストレージマウントの中核ツール
  • FUSE — rclone / AppImage が依存するユーザー空間ファイルシステム機構
  • NFS — Linux ネイティブの分散ファイルシステム(QNAP 高速接続)
  • SMB — Windows と共有する場合の標準プロトコル
  • AppArmor — Electron AppImage を安全に動かす MAC システム

外部リソース