ファイルサーバーとしても利用可能なツールとして、「OxiCloud」や「Filebrowser」を紹介しましたが、見た目が綺麗で、ファイルやフォルダの共有も行いやすい「nextExplorer」も使いやすそうです。
実際の使用画面は次のような感じで、動作も軽快。GitHubで公開されており、セルフホストが可能です。

LXDコンテナ内にDockerでセットアップ
#!/usr/bin/env bash
# =============================================================================
# nextExplorer セットアップスクリプト v3
# - /opt/nextexplorer に docker-compose.yml を配置
# - コンテナ内ポート 3000 → ホスト 127.0.0.1:3317 にバインド
# - Tailscale Serve で https://<hostname>:3317 → :3317 に追加(ポートベース)
# - 既存の Serve 設定は壊さない(--bg)
# - データディレクトリのパーミッションを正しく設定
# =============================================================================
set -euo pipefail
# ── 設定 ──────────────────────────────────────────────────────────────────────
INSTALL_DIR="/opt/nextexplorer"
HOST_PORT=3317
CONTAINER_PORT=3000
DATA_DIR="/srv/nextexplorer" # config / cache / files の実体
# コンテナ内プロセスの実行ユーザーに合わせる
# nxzai/explorer は内部で node ユーザー(uid=1000) を使用
PUID=$(id -u)
PGID=$(id -g)
# ── 色付きログ ─────────────────────────────────────────────────────────────────
info() { echo -e "\033[1;34m[INFO]\033[0m $*"; }
ok() { echo -e "\033[1;32m[ OK ]\033[0m $*"; }
warn() { echo -e "\033[1;33m[WARN]\033[0m $*"; }
die() { echo -e "\033[1;31m[ERR ]\033[0m $*" >&2; exit 1; }
# ── 前提チェック ───────────────────────────────────────────────────────────────
info "前提確認..."
command -v docker >/dev/null 2>&1 || die "docker が見つかりません"
docker compose version >/dev/null 2>&1 || die "docker compose (v2) が見つかりません"
command -v tailscale >/dev/null 2>&1 || die "tailscale が見つかりません"
tailscale status >/dev/null 2>&1 || die "Tailscale が認証されていません"
ok "前提 OK"
# ── Tailscale hostname 取得 ────────────────────────────────────────────────────
TS_HOSTNAME=$(tailscale status --json \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d['Self']['DNSName'].rstrip('.'))" \
2>/dev/null) || die "Tailscale の DNSName を取得できませんでした"
PUBLIC_URL="https://${TS_HOSTNAME}:${HOST_PORT}"
info "Tailscale ホスト : ${TS_HOSTNAME}"
info "PUBLIC_URL : ${PUBLIC_URL}"
# ── ディレクトリ作成 & パーミッション設定 ─────────────────────────────────────
info "ディレクトリ作成..."
mkdir -p "${INSTALL_DIR}"
mkdir -p "${DATA_DIR}/config"
mkdir -p "${DATA_DIR}/cache"
mkdir -p "${DATA_DIR}/files"
# コンテナ内 node(1000) / コンテナ外の実行ユーザー 両方が書けるように
# ホスト uid と合わせるか、777 で開放するかを選択
# → ここでは実行ユーザー所有 + グループ書き込み可 にする
chown -R "${PUID}:${PGID}" "${DATA_DIR}"
chmod -R u=rwX,g=rwX,o=rX "${DATA_DIR}"
# コンテナが uid=1000 で動く場合に備えて ACL を追加(acl パッケージがある場合のみ)
if command -v setfacl >/dev/null 2>&1; then
setfacl -R -m u:1000:rwX "${DATA_DIR}"
setfacl -R -d -m u:1000:rwX "${DATA_DIR}"
info "ACL: uid=1000 に rwX を付与しました"
else
# ACL が使えない場合は o+w を付与してコンテナ書き込みを許可
chmod -R o+w "${DATA_DIR}/config" "${DATA_DIR}/cache" "${DATA_DIR}/files"
warn "acl パッケージが未インストールのため chmod o+w で代替しました"
warn " sudo apt install acl で改善できます"
fi
ok "ディレクトリ & パーミッション設定完了"
# ── SESSION_SECRET 生成(既存ファイルがあれば再利用) ─────────────────────────
SECRET_FILE="${INSTALL_DIR}/.session_secret"
if [[ -f "${SECRET_FILE}" ]]; then
SESSION_SECRET=$(cat "${SECRET_FILE}")
info "既存の SESSION_SECRET を再利用します"
else
SESSION_SECRET=$(python3 -c "import secrets; print(secrets.token_hex(32))")
echo "${SESSION_SECRET}" > "${SECRET_FILE}"
chmod 600 "${SECRET_FILE}"
info "SESSION_SECRET を新規生成しました"
fi
# ── docker-compose.yml 生成 ───────────────────────────────────────────────────
info "docker-compose.yml を生成..."
cat > "${INSTALL_DIR}/docker-compose.yml" <<EOF
# nextExplorer — docker-compose.yml
# 生成日: $(date '+%Y-%m-%d %H:%M:%S')
# アクセス URL: ${PUBLIC_URL}
services:
nextexplorer:
image: nxzai/explorer:latest
container_name: nextexplorer
restart: unless-stopped
ports:
# ループバックのみ。Tailscale Serve 経由でのみアクセス可能
- "127.0.0.1:${HOST_PORT}:${CONTAINER_PORT}"
environment:
NODE_ENV: production
PORT: "${CONTAINER_PORT}"
# ポートベースの URL(サブパスなし)
PUBLIC_URL: "${PUBLIC_URL}"
# Tailscale Serve (loopback) を信頼
TRUST_PROXY: "loopback"
# 再起動をまたいでセッションを維持
SESSION_SECRET: "${SESSION_SECRET}"
# コンテナ内プロセスの UID/GID をホストに合わせる → 書き込み権限の解決
PUID: "${PUID}"
PGID: "${PGID}"
volumes:
- ${DATA_DIR}/config:/config
- ${DATA_DIR}/cache:/cache
# /mnt/<ラベル名> が UI 上のボリュームになる。必要に応じて追加
- ${DATA_DIR}/files:/mnt/Files
EOF
ok "docker-compose.yml → ${INSTALL_DIR}/docker-compose.yml"
# ── コンテナ起動 ──────────────────────────────────────────────────────────────
info "コンテナを起動..."
docker compose -f "${INSTALL_DIR}/docker-compose.yml" pull
docker compose -f "${INSTALL_DIR}/docker-compose.yml" up -d
ok "コンテナ起動完了"
# ── Tailscale Serve 設定(ポートベース) ──────────────────────────────────────
info "既存の Tailscale Serve 設定を確認..."
EXISTING_SERVE=$(tailscale serve status 2>/dev/null || true)
if echo "${EXISTING_SERVE}" | grep -q ":${HOST_PORT}"; then
warn "ポート ${HOST_PORT} はすでに Tailscale Serve に登録されています。スキップします。"
else
info "Tailscale Serve にポート ${HOST_PORT} の HTTPS プロキシを追加..."
# --bg : バックグラウンドモード(既存設定を保持したまま追加)
# --https=N : Tailnet 内で HTTPS ポート N として公開
tailscale serve --bg --https="${HOST_PORT}" "http://127.0.0.1:${HOST_PORT}"
ok "Tailscale Serve 設定追加完了"
fi
# ── 完了サマリー ──────────────────────────────────────────────────────────────
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
ok "セットアップ完了!"
echo ""
echo " アクセス URL : ${PUBLIC_URL}"
echo " 設定ファイル : ${INSTALL_DIR}/docker-compose.yml"
echo " データ領域 : ${DATA_DIR}/"
echo " ├─ config/ (DB・設定)"
echo " ├─ cache/ (サムネイルキャッシュ)"
echo " └─ files/ (公開ファイル置き場 → UI上: Files)"
echo ""
echo " ボリュームを追加したい場合:"
echo " ${INSTALL_DIR}/docker-compose.yml の volumes に"
echo " - /your/path:/mnt/LabelName を追記して"
echo " docker compose -f ${INSTALL_DIR}/docker-compose.yml up -d"
echo ""
echo " 現在の Tailscale Serve 設定:"
tailscale serve status
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
インストールが完了してアクセスすれば次のような画面が表示されるので、メールアドレスやパスワードを設定してログインします。

Locationsにフォルダを追加する方法
docker-compose.yml の volumes セクションにマウントを追加するだけです。
volumes: - /srv/nextexplorer/config:/config - /srv/nextexplorer/cache:/cache - /srv/nextexplorer/files:/mnt/Files # 既存 - /home/user/photos:/mnt/Photos # 追加例 - /mnt/nas/documents:/mnt/Documents # 追加例
/mnt/ 以降の名前(Photos、Documents など)がそのまま UI 上のラベルになります。
編集と反映するコマンド
# 編集
nano /opt/nextexplorer/docker-compose.yml
# 編集後
docker compose -f /opt/nextexplorer/docker-compose.yml up -d
デフォルトの Files フォルダを別パスに変えたい場合も同じで、既存の行のホスト側パスを書き換えるだけです。
# 変更前
- /srv/nextexplorer/files:/mnt/Files
# 変更後(例:/data/storage を Files として公開)
- /opt/lxd-data:/mnt/Files
注意点として、追加したディレクトリにコンテナ(uid=1000)が書き込む必要がある場合は、スクリプトで設定したのと同じようにパーミッションを合わせてください。
# acl が入っている場合
sudo setfacl -R -m u:1000:rwX /your/path
sudo setfacl -R -d -m u:1000:rwX /your/path
# acl なしの場合
sudo chmod -R o+w /your/path

