Rustで書かれた軽快動作の「OxiCloud」

Nextcloudは非常に多機能ですが、ちょっとファイル共有に利用したい、という場合には重量級です。そこに、Rustで書かれた「OxiCloud」が作られているというので試してみました。
現時点はv0.5.4で、まだ作成中のようですが、動作は軽快で、期待できそうな内容でした。

1コピペでインストール

LXDコンテナで実行すれば、コピペするだけでインストールされます。ビルドするので多少時間がかかりますが。

スクリプトがやること(順番に):

  1. git curl build-essential libssl-dev libpq-dev postgresql をapt導入
  2. PostgreSQLを起動してDB・ユーザーを自動作成(パスワードはランダム生成)
  3. rustup で Rust stable を /usr/local/cargo にシステムインストール
  4. /opt/oxicloud にソースをクローン(再実行時はpull)
  5. .env を自動生成(IPアドレスを自動検出)
  6. cargo build --release でビルド(初回は10〜20分かかります
  7. バイナリを /usr/local/bin/oxicloud に配置
  8. systemdサービスとして登録・起動
#!/usr/bin/env bash
# ============================================================
#  OxiCloud ネイティブインストーラー(Docker不要)
#  対象: Ubuntu/Debian 系 LXD コンテナ
#  必要: Rust 1.93+, PostgreSQL 13+(本スクリプトが導入)
# ============================================================
set -euo pipefail

# ---- ユーザー設定(変更可) ---------------------------------
INSTALL_DIR="/opt/oxicloud"
STORAGE_DIR="/var/lib/oxicloud/storage"
PORT="8086"
DB_NAME="oxicloud"
DB_USER="oxicloud"
DB_PASS="${DB_PASS:-$(openssl rand -hex 16)}"
APP_URL="${APP_URL:-}"        # 例: http://192.168.1.10:8086
RUN_USER="oxicloud"
SERVICE_NAME="oxicloud"
# ------------------------------------------------------------

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
info()  { echo -e "${GREEN}[OK]${NC}  $*"; }
warn()  { echo -e "${YELLOW}[INFO]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }

echo "======================================================"
echo "  OxiCloud ネイティブインストール開始"
echo "======================================================"

# --- 0. root 確認 ---
[ "$(id -u)" -eq 0 ] || error "root (または sudo) で実行してください"

# --- 1. APP_URL 自動補完 ---
if [ -z "$APP_URL" ]; then
  LOCAL_IP=$(hostname -I | awk '{print $1}')
  APP_URL="http://${LOCAL_IP}:${PORT}"
fi
warn "アクセスURL: $APP_URL"

# --- 2. システムパッケージ ---
warn "システムパッケージを更新・インストールします..."
apt-get update -qq
apt-get install -y --no-install-recommends \
  git curl build-essential pkg-config \
  libssl-dev libpq-dev ca-certificates \
  postgresql postgresql-client openssl
info "パッケージインストール完了"

# --- 3. PostgreSQL 起動 & DB 作成 ---
warn "PostgreSQL を設定します..."
# クラスタ番号を自動検出して起動
PG_VERSION=$(pg_lsclusters -h | awk 'NR==1{print $1}')
pg_ctlcluster "${PG_VERSION}" main start 2>/dev/null || true

# DB ユーザー・データベース作成(冪等)
su -c "psql -tc \"SELECT 1 FROM pg_roles WHERE rolname='${DB_USER}'\" | grep -q 1 || \
  psql -c \"CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASS}'\"" postgres

su -c "psql -tc \"SELECT 1 FROM pg_database WHERE datname='${DB_NAME}'\" | grep -q 1 || \
  psql -c \"CREATE DATABASE ${DB_NAME} OWNER ${DB_USER}\"" postgres

info "PostgreSQL 設定完了 (DB: ${DB_NAME}, User: ${DB_USER})"

# --- 4. Rust インストール / 更新 ---
warn "Rust ツールチェーンを確認します..."
export CARGO_HOME="/usr/local/cargo"
export RUSTUP_HOME="/usr/local/rustup"
export PATH="${CARGO_HOME}/bin:${PATH}"

if ! command -v cargo &>/dev/null && [ ! -x "${CARGO_HOME}/bin/cargo" ]; then
  warn "rustup をインストールします(数分かかります)..."
  curl -fsSL https://sh.rustup.rs | \
    RUSTUP_HOME="$RUSTUP_HOME" CARGO_HOME="$CARGO_HOME" \
    sh -s -- -y --no-modify-path --default-toolchain stable
  info "Rust インストール完了 ($(${CARGO_HOME}/bin/rustc --version))"
else
  "${CARGO_HOME}/bin/rustup" update stable --no-self-update 2>/dev/null || rustup update stable --no-self-update
  info "Rust 確認済み ($(rustc --version 2>/dev/null || ${CARGO_HOME}/bin/rustc --version))"
fi

# --- 5. ソース取得 ---
warn "OxiCloud ソースを取得します..."
if [ -d "${INSTALL_DIR}/.git" ]; then
  warn "既存リポジトリを更新します..."
  git -C "$INSTALL_DIR" fetch --tags
  git -C "$INSTALL_DIR" pull --ff-only
else
  git clone --depth 1 https://github.com/DioCrafts/oxicloud.git "$INSTALL_DIR"
  info "クローン完了"
fi

# --- 6. .env 生成 ---
warn ".env を生成します..."
cat > "${INSTALL_DIR}/.env" <<EOF
DATABASE_URL=postgres://${DB_USER}:${DB_PASS}@localhost/${DB_NAME}
OXICLOUD_DB_CONNECTION_STRING=postgres://${DB_USER}:${DB_PASS}@localhost/${DB_NAME}
APP_URL=${APP_URL}
OXICLOUD_BASE_URL=${APP_URL}
POSTGRES_DB=${DB_NAME}
POSTGRES_USER=${DB_USER}
POSTGRES_PASSWORD=${DB_PASS}
RUST_LOG=info
EOF
info ".env 生成完了"

# --- 7. ビルド ---
warn "リリースビルドを実行します(初回は10〜20分かかります)..."
cd "$INSTALL_DIR"
CARGO_HOME="$CARGO_HOME" RUSTUP_HOME="$RUSTUP_HOME" \
  "${CARGO_HOME}/bin/cargo" build --release
info "ビルド完了"

# --- 8. バイナリを配置 ---
install -m 755 "${INSTALL_DIR}/target/release/oxicloud" /usr/local/bin/oxicloud
info "バイナリを /usr/local/bin/oxicloud に配置しました"

# --- 9. 実行ユーザー & ディレクトリ ---
id "$RUN_USER" &>/dev/null || useradd -r -s /bin/false -d "$STORAGE_DIR" "$RUN_USER"
mkdir -p "$STORAGE_DIR"
chown -R "${RUN_USER}:${RUN_USER}" "$STORAGE_DIR" "$INSTALL_DIR"
info "ユーザー・ディレクトリ設定完了"

# --- 10. systemd サービス登録 ---
warn "systemd サービスを登録します..."
cat > "/etc/systemd/system/${SERVICE_NAME}.service" <<EOF
[Unit]
Description=OxiCloud - Self-hosted cloud storage
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=simple
User=${RUN_USER}
WorkingDirectory=${INSTALL_DIR}
EnvironmentFile=${INSTALL_DIR}/.env
ExecStart=/usr/local/bin/oxicloud
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=oxicloud

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable "${SERVICE_NAME}"
systemctl restart "${SERVICE_NAME}"
info "サービス起動完了"

# --- 完了 ---
echo ""
echo "======================================================"
echo "  OxiCloud インストール完了!"
echo ""
echo "  ブラウザでアクセス : ${APP_URL}"
echo "  初回アクセスで管理者アカウントを作成してください"
echo ""
echo "  ログ確認  : journalctl -u ${SERVICE_NAME} -f"
echo "  再起動    : systemctl restart ${SERVICE_NAME}"
echo "  停止      : systemctl stop ${SERVICE_NAME}"
echo ""
echo "  DB パスワード: ${DB_PASS}"
echo "  ※ 上記パスワードを安全な場所に保管してください"
echo "======================================================"

カスタマイズしたい場合:

# ポートやパスワードを指定
sudo DB_PASS=mypassword APP_URL=http://192.168.1.50:8086 bash install_oxicloud.sh

データの保存場所

ファイルデータの保存場所:

/opt/oxicloud/storage/.blobs/

SHA-256ハッシュで2文字ずつのディレクトリに分散して保存されています(00/ 01/ff/)。

メタデータの保存場所: PostgreSQL oxicloud データベース内の各スキーマ:

スキーマ内容
authユーザー・セッション・ファイル一覧
audio音楽・プレイリスト
caldavカレンダー
carddav連絡先

バックアップするべきものはこの2つ:

# ファイル実体
/opt/oxicloud/storage/

# DB
pg_dump oxicloud > oxicloud_backup.sql

別の環境にインストールする場合

「ビルド済みバイナリ+セットアップスクリプト」をセットにしておけば、毎回10〜20分のコンパイルをスキップできて大幅に楽になります。

配布パッケージとして持ち回るもの
├── oxicloud          ← cargo build --release したバイナリ (約15MB)
└── setup.sh          ← PostgreSQL設定+サービス登録だけするスクリプト

注意点:

  • バイナリはビルドしたOSのアーキテクチャ依存(x86_64/arm64)
  • Ubuntu 22.04でビルド → Ubuntu 24.04でも基本動く(glibcのバージョンが新しい方向ならOK)
  • Alpine Linuxなど musl 系には移植不可(glibcとmuslは非互換)

別の環境へセットアップするスクリプト

使い方の流れ:

【初回・ビルド環境(既存LXDコンテナ)】
# setup.sh と build_package.sh を同じフォルダに置いて
bash build_package.sh
# → oxicloud-dist.tar.gz が生成される(約15MB)

   (元環境)          (新環境)
───────────────────── ─────────────────
bash build_package.sh
→ oxicloud-dist.tar.gz 生成

│ 転送

tar xzf oxicloud-dist.tar.gz
sudo bash oxicloud-dist/setup.sh ← 実行

setup.sh は Rust を一切インストールしないので、新環境では PostgreSQLのみ を apt で入れて終わりです。所要時間は1〜2分程度です。ここではTaildropを使った転送を行いますが、何の手段で転送しても構いません。

移植できる条件:

条件内容
CPUビルド環境と同じアーキテクチャ(x86_64 or arm64)
OSUbuntu 22.04以降 / Debian 11以降(glibc 2.35+)
不要Rust、git、build-essential など

ビルド済みバイナリ + setup.sh を tar.gz にまとめる

既存LXDコンテナに入って実行

nano build_package.sh
nano setup.sh
bash build_package.sh

build_package.sh

#!/usr/bin/env bash
# ============================================================
#  OxiCloud パッケージビルダー
#  ビルド済みバイナリ + static/ + setup.sh を tar.gz にまとめる
#  実行: bash build_package.sh
#  出力: ~/oxicloud-dist.tar.gz
# ============================================================
set -euo pipefail

INSTALL_DIR="/opt/oxicloud"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DIST_DIR="${HOME}/oxicloud-dist"
OUT_TAR="${HOME}/oxicloud-dist.tar.gz"

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
info()  { echo -e "${GREEN}[OK]${NC}  $*"; }
warn()  { echo -e "${YELLOW}[INFO]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }

echo "======================================================"
echo "  OxiCloud パッケージビルド"
echo "======================================================"

# --- Rust 確認 ---
export CARGO_HOME="/usr/local/cargo"
export RUSTUP_HOME="/usr/local/rustup"
export PATH="${CARGO_HOME}/bin:${PATH}"

CARGO=""
if [ -x "${CARGO_HOME}/bin/cargo" ]; then
  CARGO="${CARGO_HOME}/bin/cargo"
elif command -v cargo &>/dev/null; then
  CARGO="$(command -v cargo)"
else
  error "cargo が見つかりません。先に install_oxicloud.sh でビルド環境を構築してください"
fi

# --- ソース確認 ---
[ -d "${INSTALL_DIR}/.git" ] || error "ソースが ${INSTALL_DIR} にありません。先に install_oxicloud.sh を実行してください"
[ -d "${INSTALL_DIR}/static" ] || error "static/ ディレクトリが ${INSTALL_DIR} にありません"

# --- setup.sh 確認 ---
SETUP="${SCRIPT_DIR}/setup.sh"
[ -f "$SETUP" ] || error "setup.sh が見つかりません: ${SETUP}"

# --- ビルド ---
warn "リリースビルドを実行します..."
cd "$INSTALL_DIR"
CARGO_HOME="$CARGO_HOME" RUSTUP_HOME="$RUSTUP_HOME" "$CARGO" build --release
info "ビルド完了"

# --- パッケージング ---
warn "パッケージをまとめます..."
rm -rf "$DIST_DIR"
mkdir -p "$DIST_DIR"

cp "${INSTALL_DIR}/target/release/oxicloud" "${DIST_DIR}/oxicloud"
cp "$SETUP" "${DIST_DIR}/setup.sh"
cp -r "${INSTALL_DIR}/static" "${DIST_DIR}/static"
chmod +x "${DIST_DIR}/oxicloud" "${DIST_DIR}/setup.sh"

# README 生成
ARCH=$(uname -m)
OS_ID=$(. /etc/os-release && echo "${ID}-${VERSION_ID}" 2>/dev/null || echo "linux")
cat > "${DIST_DIR}/README.txt" <<EOF
OxiCloud バイナリ配布パッケージ
================================
ビルド日時    : $(date '+%Y-%m-%d %H:%M:%S')
アーキテクチャ: ${ARCH}
ビルド環境    : ${OS_ID}

セットアップ手順:
  1. tailscale file cp oxicloud-dist.tar.gz 新サーバー:
  2. 新サーバーで: tailscale file get ~/
  3. 新サーバーで: mkdir oxicloud-dist && tar xzf oxicloud-dist.tar.gz -C oxicloud-dist
  4. 新サーバーで: sudo bash oxicloud-dist/setup.sh

注意:
  - 同じ CPU アーキテクチャ (${ARCH}) の Ubuntu/Debian 系でのみ動作します
  - glibc 2.35 以上が必要です (Ubuntu 22.04+)
EOF

# tar.gz 作成
rm -f "$OUT_TAR"
tar czf "$OUT_TAR" -C "${HOME}" oxicloud-dist/
rm -rf "$DIST_DIR"

SIZE=$(du -sh "$OUT_TAR" | cut -f1)
info "パッケージ作成完了: ${OUT_TAR} (${SIZE})"

echo ""
echo "======================================================"
echo "  次のステップ(Taildrop で転送):"
echo ""
echo "  tailscale file cp ${OUT_TAR} 新サーバー名:"
echo ""
echo "  新サーバーで:"
echo "  tailscale file get ~/"
echo "  mkdir oxicloud-dist && tar xzf ~/oxicloud-dist.tar.gz -C oxicloud-dist"
echo "  sudo bash oxicloud-dist/setup.sh"
echo "======================================================"

setup.sh

#!/usr/bin/env bash
# ============================================================
#  OxiCloud セットアップスクリプト(バイナリ配布版)
#  使い方: sudo bash setup.sh
#  同じディレクトリに oxicloud バイナリを置いてから実行
# ============================================================
set -euo pipefail

# ---- 設定(変更可) ----------------------------------------
INSTALL_DIR="/opt/oxicloud"
STORAGE_DIR="/var/lib/oxicloud/storage"
PORT="8086"
DB_NAME="oxicloud"
DB_USER="oxicloud"
DB_PASS="${DB_PASS:-$(openssl rand -hex 16)}"
APP_URL="${APP_URL:-}"
RUN_USER="oxicloud"
SERVICE_NAME="oxicloud"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# ------------------------------------------------------------

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
info()  { echo -e "${GREEN}[OK]${NC}  $*"; }
warn()  { echo -e "${YELLOW}[INFO]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }

echo "======================================================"
echo "  OxiCloud セットアップ(バイナリ配布版)"
echo "======================================================"

# --- 0. 前提確認 ---
[ "$(id -u)" -eq 0 ] || error "root (または sudo) で実行してください"
[ -f "${SCRIPT_DIR}/oxicloud" ] || error "oxicloud バイナリが見つかりません (${SCRIPT_DIR}/oxicloud)"

BINARY_ARCH=$(file "${SCRIPT_DIR}/oxicloud" | grep -o 'x86-64\|aarch64\|ARM' || echo "不明")
HOST_ARCH=$(uname -m)
warn "バイナリ: ${BINARY_ARCH}  /  このホスト: ${HOST_ARCH}"

# --- 1. APP_URL 自動補完 ---
if [ -z "$APP_URL" ]; then
  LOCAL_IP=$(hostname -I | awk '{print $1}')
  APP_URL="http://${LOCAL_IP}:${PORT}"
fi
warn "アクセスURL: $APP_URL"

# --- 2. 最小パッケージ導入(Rust不要) ---
warn "依存パッケージをインストールします..."
apt-get update -qq
apt-get install -y --no-install-recommends \
  postgresql postgresql-client openssl ca-certificates libpq5
info "パッケージインストール完了"

# --- 3. PostgreSQL 起動 & DB 作成 ---
warn "PostgreSQL を設定します..."
PG_VERSION=$(pg_lsclusters -h | awk 'NR==1{print $1}')
pg_ctlcluster "${PG_VERSION}" main start 2>/dev/null || true

su -c "psql -tc \"SELECT 1 FROM pg_roles WHERE rolname='${DB_USER}'\" | grep -q 1 || \
  psql -c \"CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASS}'\"" postgres

su -c "psql -tc \"SELECT 1 FROM pg_database WHERE datname='${DB_NAME}'\" | grep -q 1 || \
  psql -c \"CREATE DATABASE ${DB_NAME} OWNER ${DB_USER}\"" postgres

info "PostgreSQL 設定完了 (DB: ${DB_NAME}, User: ${DB_USER})"

# --- 4. バイナリ配置 ---
warn "バイナリを配置します..."
mkdir -p "$INSTALL_DIR"
install -m 755 "${SCRIPT_DIR}/oxicloud" /usr/local/bin/oxicloud
info "バイナリを /usr/local/bin/oxicloud に配置しました"

# --- 5. .env 生成 ---
cat > "${INSTALL_DIR}/.env" <<EOF
DATABASE_URL=postgres://${DB_USER}:${DB_PASS}@localhost/${DB_NAME}
OXICLOUD_DB_CONNECTION_STRING=postgres://${DB_USER}:${DB_PASS}@localhost/${DB_NAME}
APP_URL=${APP_URL}
OXICLOUD_BASE_URL=${APP_URL}
POSTGRES_DB=${DB_NAME}
POSTGRES_USER=${DB_USER}
POSTGRES_PASSWORD=${DB_PASS}
RUST_LOG=info
EOF
info ".env 生成完了"

# --- 6. 実行ユーザー & ストレージディレクトリ ---
id "$RUN_USER" &>/dev/null || useradd -r -s /bin/false -d "$STORAGE_DIR" "$RUN_USER"
mkdir -p "$STORAGE_DIR"
chown -R "${RUN_USER}:${RUN_USER}" "$STORAGE_DIR" "$INSTALL_DIR"
info "ユーザー・ディレクトリ設定完了"

# --- 7. systemd サービス登録 ---
warn "systemd サービスを登録します..."
cat > "/etc/systemd/system/${SERVICE_NAME}.service" <<EOF
[Unit]
Description=OxiCloud - Self-hosted cloud storage
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=simple
User=${RUN_USER}
WorkingDirectory=${INSTALL_DIR}
EnvironmentFile=${INSTALL_DIR}/.env
ExecStart=/usr/local/bin/oxicloud
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=oxicloud

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable "${SERVICE_NAME}"
systemctl restart "${SERVICE_NAME}"
info "サービス起動完了"

# --- 完了 ---
echo ""
echo "======================================================"
echo "  OxiCloud セットアップ完了!"
echo ""
echo "  ブラウザでアクセス : ${APP_URL}"
echo "  初回アクセスで管理者アカウントを作成してください"
echo ""
echo "  ログ確認  : journalctl -u ${SERVICE_NAME} -f"
echo "  再起動    : systemctl restart ${SERVICE_NAME}"
echo "  停止      : systemctl stop ${SERVICE_NAME}"
echo ""
echo "  DB パスワード: ${DB_PASS}"
echo "  ※ 上記パスワードを安全な場所に保管してください"
echo "======================================================"

Taildropで送信

ビルド環境で

tailscale file cp ~/oxicloud-dist.tar.gz 新サーバー名:

新環境で

tailscale file get ~/
mkdir oxicloud-dist && tar xzf ~/oxicloud-dist.tar.gz -C oxicloud-dist
sudo bash oxicloud-dist/setup.sh
タイトルとURLをコピーしました