🎯 はじめに:この記事のスコープ
本記事はシリーズ 「脱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 間のファイルアクセスに迷わなくなります。

| 層 | 実体 | 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 ローカル層 | 内蔵 SSD | C:\... | ~/... | 一時ビルド成果物・キャッシュ・I/O 速度を求めるもの |
用途別ファイル配置の指針
| データ種別 | 配置先 | 理由 |
|---|---|---|
開発設定(~/.aws、~/.config/gcloud 等) | L1 Drive | 両 OS 間 + 複数 PC 間で共有(第 4 回 DevContainer の bind mount と組み合わせ) |
| 業務ドキュメント(提案書・議事録・契約書) | L1 Drive | バージョン履歴・共有・全文検索 |
| 大容量メディア(動画素材・ISO・バックアップ) | L2 NAS | クラウド容量と帯域の節約 |
一時ビルド成果物(node_modules / dist) | L3 ローカル | 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 Desktop(G: ドライブ)と同じ感覚で、Ubuntu 側に ~/GoogleDrive/ をマウントするのが本フェーズのゴールです。実体はクラウド側、ローカルはキャッシュのみという「ストリーミング同期」モデルで、両 OS から同じファイルが見えます。仕組みとしてはユーザー空間のプログラムから FUSE 経由でカーネルにマウント要求を出す形です。
rclone のインストール(snap / apt の罠)
rclone は Ubuntu に 3 通りで入りますが、実用に堪えるのは公式スクリプトのみです。
| 方法 | バージョン | 制約 | 推奨度 |
|---|---|---|---|
sudo snap install rclone | 1.73.5(新しい) | サンドボックス内動作で Dolphin / DevContainer から見えない | △ |
sudo apt install rclone | 1.60.1(古い) | VFS キャッシュの新オプションが使えない | △ |
| 公式スクリプト | 最新 | 制約なし | ◎ 推奨 |
snap 版を選ぶと、rclone でマウントした ~/GoogleDrive が rclone プロセスの名前空間外(= 他のアプリ)から見えない症状にぶつかります。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.conf で user_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-mode | off / writes | full | 読み込みもキャッシュ → 同じファイルを繰り返し読む際の API 呼び出しが激減 ◎ |
--vfs-cache-max-size | なし | 20G | キャッシュ上限。容量超過は古いものから自動削除 |
--vfs-cache-max-age | なし | 168h(1 週間) | 古いキャッシュを自動削除 |
--vfs-read-chunk-size | 128M | 64M | 大ファイル読み込みのチャンク単位 |
--vfs-read-chunk-size-limit | なし | 1G | チャンクサイズ動的拡大の上限 |
--dir-cache-time | 5m | 1h | ディレクトリ一覧のキャッシュ時間 |
--poll-interval | 1m | 1m | クラウド側変更検知の頻度 |
--buffer-size | 16M | 256M | 読み込みバッファ(16 倍) |
--transfers | 4 | 8 | 並列転送数 |
--tpslimit | なし | 10 | API レート制限予防(重要) |
--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 を準備
- console.cloud.google.com にログイン(Drive にアクセスするアカウントと別でも可)
- **「プロジェクトの選択」→「新しいプロジェクト」**で
rcloneプロジェクトを新規作成(既存の本番 GCP プロジェクトとは分離) - **「有効な 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/docs | Google ドキュメント等の Drive 内ネイティブ形式アクセス |
auth/drive | Drive 全体への読み書きアクセス |
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 からのアクセスでは、NFS と SMB の両方が利用可能です。Windows と共有するフォルダは SMB、Linux 専用フォルダは NFS、というハイブリッド構成が現実解です。
| 項目 | SMB(CIFS) | NFS |
|---|---|---|
| 速度(GbE 環境) | 100〜200 MB/s | 200〜300 MB/s(GbE 上限近く) |
| CPU 負荷 | 中 | 低 |
| Linux ネイティブ性 | △ | ◎ |
| 認証方式 | ユーザー / パスワード | UID/GID ベース |
| Wayland + KDE 統合 | 不安定なケースあり | 問題なし |
| Windows との共有 | ◎ | × (Windows は別途 NFS クライアント有効化が必要) |
⚠️ NFS はホストベース認証(送信元 IP で許可制御)なので、信頼できる社内 LAN 内での利用が前提。インターネット越しに NFS を使うのは絶対 NG。
速度実測(GbE / TS-431X2 / RAID5)
| 操作 | NFS v4.1 | SMB 3.0 |
|---|---|---|
| Sequential Write | 100〜115 MB/s | 90〜110 MB/s |
| Sequential Read | 105〜118 MB/s | 95〜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 ホストアクセス
| 設定項目 | 推奨値 |
|---|---|
| アクセス権 | 読み取り / 書き込み |
| ホスト / IP | 192.168.1.0/24(LAN 全体) または特定 IP |
| Squash オプション | squash なし(UID/GID 透過) |
| Anonymous GID/UID | 触らない |
| セキュリティ | sys(NFS v4 でも標準) |
Squash の意味(参考)
| Squash | 動作 |
|---|---|
| squash なし | クライアントの UID/GID をそのまま使用(推奨) |
| root squash | root だけ匿名にマッピング |
| 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
主要オプションの意味
| オプション | 意味 |
|---|---|
nfs4 | NFS v4 を使用 |
_netdev | ネットワーク利用可能まで待機 |
nofail | NAS 不在でもブートを止めない(重要) |
x-systemd.automount | アクセス時マウント(高速ブート) |
x-systemd.idle-timeout=600 | 10 分アイドルで自動アンマウント |
vers=4.1 | NFS v4.1 を明示(QNAP 互換性が高い) |
rsize=1048576 / wsize=1048576 | 1 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 だと繋がらない」**という切り分けにくい症状になります。
切り分け手順
- Public 共有でテスト — 匿名アクセス OK の共有を作って Linux からアクセス → 通れば「admin の SMB は OK だが匿名フェーズが弾かれている」と確定
- QNAP の上記設定を確認 → 「有効(厳格)」を 「無効」 に変更
- 再度 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.1 を vers=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 のみ | ❌ |
sysctl で userns 制限解除 | △ システム全体緩和 | 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 install | user 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 全般に適用できます。
| アプリ | 用途 | プロファイル名 |
|---|---|---|
| Cursor | AI 統合エディタ(VS Code フォーク) | /etc/apparmor.d/cursor |
| Insomnia | API テスト | /etc/apparmor.d/insomnia |
| Postman | API テスト | /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 は「他デバイスへの配布チャネル + バックアップ」という分担です。
devcontainer.json のマウント設定
.devcontainer/devcontainer.json の mounts または 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.conf で user_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_DENIED | 中 | QNAP の Microsoft Networking 詳細で「無効」に変更 |
NFS v4 idmap ドメイン不一致で全員 nobody:nogroup | 中 | /etc/idmapd.conf の Domain を 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.confのDomainを 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 全体戦略・総論 | 値上げ背景・ロードマップ・コスト・リスク |
| 2 | Windows 11 + Ubuntu デュアルブート構築 | M.2 物理分離・KDE Plasma・GRUB |
| 3 | Ubuntu PC セットアップ | NVIDIA ドライバ事後導入・サスペンド無効化・Bluetooth・ターミナル選定 |
| 4 | Ubuntu 開発環境セットアップ | Docker Engine ネイティブ・DevContainer 機密情報マウント・Claude Code |
| 5 | Ubuntu データ共有セットアップ(本記事) | rclone Drive + systemd・QNAP NFS/SMB・Obsidian Vault・AppArmor |
| 6 | Microsoft 365 → Google Workspace 全面移行 | メール・SSO・MFA・MX 切替 + OneDrive → Google Drive ファイル移行・共有リンク・コスト最適化 |
| 7 | Ubuntu リモート開発セットアップ | Tailscale + SSH + VS Code Remote / DevContainer・Wayland ホスト |
| 8 | ActiveReports → Playwright + Scriban 移行(公開予定) | 帳票エンジン置換・バーコード・印刷品質 PDF |
| 9 | コスト削減効果と 1 年運用レビュー(公開予定) | 実績ベースのコスト・運用上のハマりどころ |
🔗 関連リソース
CTS-KB 内の関連記事
- Ubuntu 開発環境セットアップ — シリーズ第 4 回(DevContainer の認証情報 bind mount 設計)
関連用語
- rclone — クラウドストレージマウントの中核ツール
- FUSE — rclone / AppImage が依存するユーザー空間ファイルシステム機構
- NFS — Linux ネイティブの分散ファイルシステム(QNAP 高速接続)
- SMB — Windows と共有する場合の標準プロトコル
- AppArmor — Electron AppImage を安全に動かす MAC システム