Nextcloudよりも軽快な動作でファイルを管理できる「OpenCloud」

比較的動作の重い「Nextcloud」と比べ、「OpenCloud」は動作が圧倒的に軽いというのを見かけたので試してみました。
OpenCloudは、Google DriveやOneDriveのように自社や個人でサーバーを構築できる「セルフホスト型クラウドストレージ」で、元々はownCloudの開発者が立ち上げたプロジェクトであり、ownCloudの次世代アーキテクチャ(oCIS)をベースにコミュニティ主導でフォーク(派生・独立)して誕生したそうです。

従来主流のownCloudやNextcloud(PHP製)とは異なり、Go言語で完全に書き直されているため、メモリ消費が少なく動作が非常に軽快です。専用データベース不要: 動作に複雑なデータベースサーバーを必要とせず、手軽に構築できるそうです。

2種類の動作モード

ファイルをサーバーの物理ディスクにどのように保存・管理するかを決めるドライバの違いで、DecomposedFSPosixFSがあるようです。両者の最も大きな違いは、「人間がサーバーの裏側(エクスプローラーやSSHなど)から見て、ファイル構造がそのまま読めるかどうか」にあります。

1. DecomposedFS モード(分散管理型)

メタデータ(ファイル名やフォルダ構造の階層情報)と、実データ(ファイルの中身=Blob)を完全に切り離してバラバラに保存する方式です。

  • 保存のされ方:
    サーバー内では、ファイルが「UUID(f47ac10b-58cc... のようなランダムな英数字)」のフォルダに細かく暗号化されたような状態で保存されます。人間が見てもどれが何のファイルか一切わかりません。
  • メリット:
    • 圧倒的なスケーラビリティ: 大規模な環境や、裏側にS3などのオブジェクトストレージを組み合わせた運用(DecomposedS3)が非常に得意です。
    • 機能の安定性: クラウドストレージ特有の「ファイルのバージョン管理」や「ゴミ箱機能」、高速なID検索がスムーズに行えます。
  • デメリット:
    • ベンダーロックイン: OpenCloudのシステムを通さないと、データを復元したり直接ファイルを取り出したりすることができません。

2. PosixFS モード(ネイティブファイルシステム型)

OpenCloudの画面上で作ったフォルダ階層やファイル名を、サーバーのローカルディスク(Linux等)にそのままの形で保存する方式です。

  • 保存のされ方:
    OpenCloud上で「写真/2026年/trip.jpg」という配置にすれば、サーバーのディレクトリ上にもそのまま「写真/2026年/trip.jpg」として保存されます。
  • メリット:
    • データの完全な個人所有(脱ロックイン): 万が一OpenCloudがバグやトラブルで起動しなくなっても、物理ディスクからファイルをそのままコピーして救出できます。
    • 他アプリとの連携: サーバー側で同じディレクトリをPlexやNavidrome(メディアサーバー)、あるいは別のファイル共有(Samba等)にそのまま読み込ませて共有・活用できます。
  • デメリット:
    • 高度な機能の制限: コラボレーションや高度なバージョン管理をする場合、ストレージ側に拡張属性(Extended Attributes)のサポートが必要になるなど、環境依存や制約が生まれます

DecomposedFSモードでインストール

まずは普通にDecomposedFSモードでインストールしてみました。

#!/bin/bash
set -euo pipefail

# ===== OpenCloud installer (Docker Compose + Tailscale Serve) =====
PORT=3328
INSTALL_DIR=/opt/OpenCloud
LOCAL_PORT=9200
OC_IMAGE="opencloudeu/opencloud-rolling:6.2.0"
DEFAULT_DATA_ROOT="/opt/lxd-data"

echo "==> 前提チェック"
command -v docker >/dev/null 2>&1 || { echo "Docker が見つかりません。先に Docker をインストールしてください。"; exit 1; }
command -v tailscale >/dev/null 2>&1 || { echo "tailscale コマンドが見つかりません。"; exit 1; }
if ! tailscale status >/dev/null 2>&1; then
  echo "Tailscale が認証されていません。'tailscale up' を実行してください。"
  exit 1
fi

echo "==> Tailnet ホスト名を取得"
TS_FQDN=$(tailscale status --self --json | grep -o '"DNSName": *"[^"]*"' | head -1 | cut -d'"' -f4 | sed 's/\.$//')
if [ -z "$TS_FQDN" ]; then
  echo "Tailnet のホスト名取得に失敗しました。"
  exit 1
fi
echo "    -> ${TS_FQDN}"

echo ""
echo "==> データ保存先のルートディレクトリを指定してください"
read -r -p "データルート [${DEFAULT_DATA_ROOT}]: " DATA_ROOT
DATA_ROOT="${DATA_ROOT:-${DEFAULT_DATA_ROOT}}"
DATA_ROOT="${DATA_ROOT%/}"

OC_DATA_DIR="${DATA_ROOT}/opencloud/data"
OC_CONFIG_DIR="${DATA_ROOT}/opencloud/config"
echo "    -> データ: ${OC_DATA_DIR}"
echo "    -> 設定 : ${OC_CONFIG_DIR}"

sudo mkdir -p "${OC_DATA_DIR}" "${OC_CONFIG_DIR}"
# コンテナ内は UID/GID 1000 で動作するため所有権を合わせる
sudo chown -R 1000:1000 "${OC_DATA_DIR}" "${OC_CONFIG_DIR}"

echo "==> ${INSTALL_DIR} を準備(compose ファイル等の管理用ディレクトリ)"
sudo mkdir -p "${INSTALL_DIR}"
sudo chown "$(id -u)":"$(id -g)" "${INSTALL_DIR}"
cd "${INSTALL_DIR}"

# 既存データがあるかチェック(内蔵IDMはパスワードを初回起動時に焼き付けるため、
# 一度でも起動済みの場合は環境変数を変えても反映されない)
RESET_DATA=false
if [ -n "$(ls -A "${OC_DATA_DIR}" 2>/dev/null)" ]; then
  echo ""
  echo "指定したデータディレクトリは空ではありません(既存の OpenCloud データの可能性)。"
  echo "ログインできない場合、過去のインストールで別のパスワードが既に内蔵LDAPに保存されている可能性があります。"
  read -r -p "完全に初期化してパスワードを再設定しますか? [y/N]: " ANSWER
  if [[ "${ANSWER}" =~ ^[Yy]$ ]]; then
    RESET_DATA=true
  fi
fi

echo ""
echo "==> 管理者パスワードを設定します(ユーザー名は内蔵IDMの仕様上 'admin' 固定です)"
while true; do
  read -r -s -p "管理者(admin)パスワードを入力: " ADMIN_PASSWORD
  echo ""
  read -r -s -p "確認のためもう一度入力: " ADMIN_PASSWORD_CONFIRM
  echo ""
  if [ "${ADMIN_PASSWORD}" != "${ADMIN_PASSWORD_CONFIRM}" ]; then
    echo "パスワードが一致しません。もう一度入力してください。"
    continue
  fi
  if [ "${#ADMIN_PASSWORD}" -lt 8 ]; then
    echo "パスワードは8文字以上にしてください。"
    continue
  fi
  break
done

cat > .env <<EOF
ADMIN_PASSWORD=${ADMIN_PASSWORD}
OC_DATA_DIR=${OC_DATA_DIR}
OC_CONFIG_DIR=${OC_CONFIG_DIR}
EOF
chmod 600 .env

echo "==> docker-compose.yml を作成"
cat > docker-compose.yml <<EOF
services:
  opencloud:
    image: ${OC_IMAGE}
    container_name: opencloud
    restart: unless-stopped
    entrypoint: ["/bin/sh"]
    # opencloud init は初回のみ成功し、2回目以降は既に設定済みのためエラーになるが無視して起動する
    command: ["-c", "opencloud init || true; opencloud server"]
    environment:
      OC_URL: "https://${TS_FQDN}:${PORT}"
      PROXY_HTTP_ADDR: "0.0.0.0:${LOCAL_PORT}"
      PROXY_TLS: "false"
      OC_INSECURE: "false"
      IDM_CREATE_DEMO_USERS: "false"
      # IDM_ADMIN_PASSWORD が実際に反映される変数(INITIAL_ADMIN_PASSWORD は反映されないケースがある)
      IDM_ADMIN_PASSWORD: "\${ADMIN_PASSWORD}"
      INITIAL_ADMIN_PASSWORD: "\${ADMIN_PASSWORD}"
      OC_LOG_LEVEL: "warning"
    ports:
      - "127.0.0.1:${LOCAL_PORT}:${LOCAL_PORT}"
    volumes:
      - \${OC_DATA_DIR}:/var/lib/opencloud
      - \${OC_CONFIG_DIR}:/etc/opencloud
EOF

if [ "${RESET_DATA}" = true ]; then
  echo "==> 既存データを削除して初期化"
  docker compose down 2>/dev/null || true
  sudo rm -rf "${OC_DATA_DIR:?}"/* "${OC_CONFIG_DIR:?}"/* 2>/dev/null || true
fi

echo "==> コンテナ起動"
docker compose up -d

echo "==> OpenCloud の起動待機"
READY=false
for i in $(seq 1 30); do
  if curl -s -o /dev/null -w "%{http_code}" "http://127.0.0.1:${LOCAL_PORT}" | grep -qE "^[23]"; then
    READY=true
    echo "    -> 起動確認OK"
    break
  fi
  sleep 2
done
if [ "${READY}" = false ]; then
  echo "    -> タイムアウトしました。'docker compose logs -f' でログを確認してください。"
fi

echo "==> Tailscale Serve 設定(他サービスの設定は変更しません)"
sudo tailscale serve --bg --https="${PORT}" "http://127.0.0.1:${LOCAL_PORT}"

echo ""
echo "================================================"
echo " OpenCloud のセットアップが完了しました"
echo "   URL       : https://${TS_FQDN}:${PORT}"
echo "   ユーザー  : admin"
echo "   パスワード: (入力したものを使用してください)"
echo "   データ    : ${OC_DATA_DIR}"
echo "   設定      : ${OC_CONFIG_DIR}"
echo "================================================"
echo ""
echo "もしログインできない場合:"
echo "  1) docker compose -f ${INSTALL_DIR}/docker-compose.yml logs -f opencloud でエラーを確認"
echo "  2) このスクリプトを再実行し、初期化(y)を選択して再構築してください"

PosixFSモードでインストール

次にPosixFSモードです。ファイルを追加した場合は ‘docker compose restart opencloud' で再スキャンさせるようです。

#!/bin/bash
set -euo pipefail

# ===== OpenCloud installer (Docker Compose + Tailscale Serve, PosixFS storage) =====
PORT=3328
INSTALL_DIR=/opt/OpenCloud
LOCAL_PORT=9200
OC_IMAGE="opencloudeu/opencloud-rolling:6.2.0"
DEFAULT_DATA_ROOT="/opt/lxd-data"

echo "==> 前提チェック"
command -v docker >/dev/null 2>&1 || { echo "Docker が見つかりません。先に Docker をインストールしてください。"; exit 1; }
command -v tailscale >/dev/null 2>&1 || { echo "tailscale コマンドが見つかりません。"; exit 1; }
if ! tailscale status >/dev/null 2>&1; then
  echo "Tailscale が認証されていません。'tailscale up' を実行してください。"
  exit 1
fi

echo "==> Tailnet ホスト名を取得"
TS_FQDN=$(tailscale status --self --json | grep -o '"DNSName": *"[^"]*"' | head -1 | cut -d'"' -f4 | sed 's/\.$//')
if [ -z "$TS_FQDN" ]; then
  echo "Tailnet のホスト名取得に失敗しました。"
  exit 1
fi
echo "    -> ${TS_FQDN}"

echo ""
echo "==> データ保存先のルートディレクトリを指定してください"
read -r -p "データルート [${DEFAULT_DATA_ROOT}]: " DATA_ROOT
DATA_ROOT="${DATA_ROOT:-${DEFAULT_DATA_ROOT}}"
DATA_ROOT="${DATA_ROOT%/}"

OC_DATA_DIR="${DATA_ROOT}/opencloud/data"
OC_CONFIG_DIR="${DATA_ROOT}/opencloud/config"
echo "    -> データ: ${OC_DATA_DIR}"
echo "    -> 設定 : ${OC_CONFIG_DIR}"
echo "    (PosixFS のファイル実体は ${OC_DATA_DIR}/posix-storage 配下に、"
echo "     ユーザー名/フォルダ名のまま見える形で保存されます)"

sudo mkdir -p "${OC_DATA_DIR}" "${OC_CONFIG_DIR}"
# コンテナ内は UID/GID 1000 で動作するため所有権を合わせる
sudo chown -R 1000:1000 "${OC_DATA_DIR}" "${OC_CONFIG_DIR}"

echo "==> ${INSTALL_DIR} を準備(compose ファイル等の管理用ディレクトリ)"
sudo mkdir -p "${INSTALL_DIR}"
sudo chown "$(id -u)":"$(id -g)" "${INSTALL_DIR}"
cd "${INSTALL_DIR}"

# 既存データがあるかチェック。
# DecomposedFS -> PosixFS のような切り替えはマイグレーションパスがないため、
# 既存データがある場合は初期化必須。
RESET_DATA=false
if [ -n "$(ls -A "${OC_DATA_DIR}" 2>/dev/null)" ]; then
  echo ""
  echo "指定したデータディレクトリは空ではありません。"
  echo "ストレージドライバ(DecomposedFS/PosixFS)の切り替えはマイグレーションできないため、"
  echo "既存データがある場合は初期化が必須です。"
  read -r -p "完全に初期化して PosixFS で作り直しますか? [y/N]: " ANSWER
  if [[ "${ANSWER}" =~ ^[Yy]$ ]]; then
    RESET_DATA=true
  else
    echo "初期化しない場合、PosixFS への切り替えが正しく動作しない可能性があります。"
  fi
fi

echo ""
echo "==> 管理者パスワードを設定します(ユーザー名は内蔵IDMの仕様上 'admin' 固定です)"
while true; do
  read -r -s -p "管理者(admin)パスワードを入力: " ADMIN_PASSWORD
  echo ""
  read -r -s -p "確認のためもう一度入力: " ADMIN_PASSWORD_CONFIRM
  echo ""
  if [ "${ADMIN_PASSWORD}" != "${ADMIN_PASSWORD_CONFIRM}" ]; then
    echo "パスワードが一致しません。もう一度入力してください。"
    continue
  fi
  if [ "${#ADMIN_PASSWORD}" -lt 8 ]; then
    echo "パスワードは8文字以上にしてください。"
    continue
  fi
  break
done

cat > .env <<EOF
ADMIN_PASSWORD=${ADMIN_PASSWORD}
OC_DATA_DIR=${OC_DATA_DIR}
OC_CONFIG_DIR=${OC_CONFIG_DIR}
EOF
chmod 600 .env

echo "==> docker-compose.yml を作成"
cat > docker-compose.yml <<EOF
services:
  opencloud:
    image: ${OC_IMAGE}
    container_name: opencloud
    restart: unless-stopped
    entrypoint: ["/bin/sh"]
    # opencloud init は初回のみ成功し、2回目以降は既に設定済みのためエラーになるが無視して起動する
    command: ["-c", "opencloud init || true; opencloud server"]
    environment:
      OC_URL: "https://${TS_FQDN}:${PORT}"
      PROXY_HTTP_ADDR: "0.0.0.0:${LOCAL_PORT}"
      PROXY_TLS: "false"
      OC_INSECURE: "false"
      IDM_CREATE_DEMO_USERS: "false"
      # IDM_ADMIN_PASSWORD が実際に反映される変数(INITIAL_ADMIN_PASSWORD は反映されないケースがある)
      IDM_ADMIN_PASSWORD: "\${ADMIN_PASSWORD}"
      INITIAL_ADMIN_PASSWORD: "\${ADMIN_PASSWORD}"
      OC_LOG_LEVEL: "warning"
      # ---- PosixFS ストレージドライバ ----
      # ファイルを人間が読める「ユーザー名/フォルダ/ファイル名」構造のまま保存する
      STORAGE_USERS_DRIVER: "posix"
      STORAGE_USERS_POSIX_ROOT: "/var/lib/opencloud/posix-storage"
      STORAGE_USERS_POSIX_WATCH_TYPE: "inotifywait"
      STORAGE_USERS_ID_CACHE_STORE: "nats-js-kv"
      STORAGE_USERS_ID_CACHE_STORE_NODES: "localhost:9233"
    ports:
      - "127.0.0.1:${LOCAL_PORT}:${LOCAL_PORT}"
    volumes:
      - \${OC_DATA_DIR}:/var/lib/opencloud
      - \${OC_CONFIG_DIR}:/etc/opencloud
EOF

if [ "${RESET_DATA}" = true ]; then
  echo "==> 既存データを削除して初期化"
  docker compose down 2>/dev/null || true
  sudo rm -rf "${OC_DATA_DIR:?}"/* "${OC_CONFIG_DIR:?}"/* 2>/dev/null || true
fi

echo "==> コンテナ起動"
docker compose up -d

echo "==> OpenCloud の起動待機(PosixFS は初回にツリー全体をスキャンするため少し時間がかかります)"
READY=false
for i in $(seq 1 40); do
  if curl -s -o /dev/null -w "%{http_code}" "http://127.0.0.1:${LOCAL_PORT}" | grep -qE "^[23]"; then
    READY=true
    echo "    -> 起動確認OK"
    break
  fi
  sleep 3
done
if [ "${READY}" = false ]; then
  echo "    -> タイムアウトしました。'docker compose logs -f' でログを確認してください。"
fi

echo "==> Tailscale Serve 設定(他サービスの設定は変更しません)"
sudo tailscale serve --bg --https="${PORT}" "http://127.0.0.1:${LOCAL_PORT}"

echo ""
echo "================================================"
echo " OpenCloud のセットアップが完了しました(PosixFS)"
echo "   URL       : https://${TS_FQDN}:${PORT}"
echo "   ユーザー  : admin"
echo "   パスワード: (入力したものを使用してください)"
echo "   データ    : ${OC_DATA_DIR}"
echo "   設定      : ${OC_CONFIG_DIR}"
echo "   ファイル実体: ${OC_DATA_DIR}/posix-storage/ 配下"
echo "               (ユーザー/フォルダ名のまま見えます)"
echo "================================================"
echo ""
echo "注意:"
echo "  ・非コラボレーティブモードでは、稼働中にファイルツリーを外部から直接変更しないでください。"
echo "    ファイルを追加した場合は 'docker compose restart opencloud' で再スキャンさせてください。"
echo "  ・ログインできない場合:"
echo "    1) docker compose -f ${INSTALL_DIR}/docker-compose.yml logs -f opencloud でエラーを確認"
echo "    2) このスクリプトを再実行し、初期化(y)を選択して再構築してください"

所感

動作は確かに高速で、きびきびと表示されます。機能面よりも速度を重視するならNextcloudよりも良さそうですね。モバイルクライアントもあるので同期も楽そうです。App Storeで、Nextcloudのように機能を追加できるようです。

ただ、色々試してみたものの、やはりエクスプローラのファイルがそのまま見えるほうが好きなので。バックアップなどの管理がしやすくなりますから。そういった意味では、機能面ははるかに少なくなりますが、nextExplorerくらいシンプルなほうが良いかもです。
あとはFileRunも少し気になりますが。

タイトルとURLをコピーしました