FileBrowser / entrypoint.sh
jualhosting's picture
Upload 4 files
002a6d2 verified
Raw
History Blame Contribute Delete
6.99 kB
#!/bin/bash
# Define paths
CONFIG_PATH="/tmp/rclone.conf"
DB_PATH="/tmp/filebrowser.db"
DATA_DIR="/data"
# Check if RCLONE_CONFIG_DATA secret is set
if [ -z "$RCLONE_CONFIG_DATA" ]; then
echo "RCLONE_CONFIG_DATA is missing. Starting setup guide server on port 7860..."
# Start a simple python server to show the configuration guide
python3 -m http.server 7860 --directory /home/user/setup_guide
exit 0
fi
# Write the rclone config file
echo "$RCLONE_CONFIG_DATA" > "$CONFIG_PATH"
chmod 600 "$CONFIG_PATH"
# Extract the remote name dynamically using Python (robust against newlines and spaces)
REMOTE_NAME=$(python3 -c "
import configparser
config = configparser.ConfigParser()
try:
config.read('$CONFIG_PATH')
sections = config.sections()
if sections:
print(sections[0].strip())
else:
print('')
except Exception:
print('')
")
if [ -z "$REMOTE_NAME" ]; then
echo "Failed to parse remote name from rclone config. Using fallback 'gdrive'."
REMOTE_NAME="gdrive"
fi
# Determine the remote path (root or subfolder) to prevent exceeding Hugging Face's 50GB limit
if [ -n "$RCLONE_REMOTE_PATH" ]; then
# Trim leading/trailing slashes
CLEAN_PATH=$(echo "$RCLONE_REMOTE_PATH" | sed -e 's/^\///' -e 's/\/$//')
REMOTE_PATH="$REMOTE_NAME:$CLEAN_PATH"
echo "Using subfolder path: $REMOTE_PATH"
else
REMOTE_PATH="$REMOTE_NAME:"
echo "Using root path: $REMOTE_PATH"
fi
# Set shared-with-me flag if requested
SHARED_FLAG=""
if [ "$RCLONE_SHARED_WITH_ME" = "true" ]; then
SHARED_FLAG="--drive-shared-with-me"
echo "Rclone will access 'Shared with me' files/folders."
fi
# Ensure SQLite database file exists so inotifywait can monitor it
touch "$DB_PATH"
# 1. Download database from Google Drive if it exists
echo "Checking for persistent database on Google Drive..."
rclone copyto "$REMOTE_PATH/.filebrowser.db" "$DB_PATH" --config "$CONFIG_PATH" --drive-skip-shortcuts --drive-acknowledge-abuse $SHARED_FLAG || true
# Initialize config if export fails (e.g. database doesn't exist or is empty)
if ! filebrowser config export -d "$DB_PATH" >/dev/null 2>&1; then
echo "Initializing database..."
filebrowser config init -d "$DB_PATH"
filebrowser config set --root "$DATA_DIR" -d "$DB_PATH"
fi
# Enable Command Runner (shell execution) globally
echo "Enabling Command Runner globally..."
filebrowser config set --disable-exec=false --commands "zip,unzip,wget,curl,ls" -d "$DB_PATH"
# Configure admin password and execution permissions via FILEBROWSER_PASSWORD secret if set
if [ -n "$FILEBROWSER_PASSWORD" ]; then
echo "FILEBROWSER_PASSWORD secret is set. Configuring admin password..."
# Set or update the admin user password and execution permissions
echo "Setting admin user password..."
if filebrowser users update admin --password "$FILEBROWSER_PASSWORD" --commands "zip,unzip,wget,curl,ls" --perm.execute=true -d "$DB_PATH" >/dev/null 2>&1; then
echo "Admin password and permissions updated successfully."
else
echo "Admin user not found. Creating admin user with custom password..."
filebrowser users add admin "$FILEBROWSER_PASSWORD" --perm.admin --perm.execute=true --commands "zip,unzip,wget,curl,ls" -d "$DB_PATH"
fi
else
# Even if password secret is not set, ensure default admin has execute permissions
echo "Updating default admin user commands and permissions..."
filebrowser users update admin --commands "zip,unzip,wget,curl,ls" --perm.execute=true -d "$DB_PATH" || true
fi
# 2. Download files from Google Drive to local /data directory
echo "Syncing files from Google Drive..."
rclone copy "$REMOTE_PATH" "$DATA_DIR" --config "$CONFIG_PATH" --drive-skip-shortcuts --drive-acknowledge-abuse $SHARED_FLAG || true
# 3. Start background sync loops
# Loop A: Sync files in /data to Google Drive when modified (Debounced & Robust)
(
echo "Starting file sync daemon..."
LAST_EVENT_FILE="/tmp/last_event_time"
PENDING_FILE="/tmp/sync_pending"
DEBOUNCE_SECS=10
# Clear any old state
rm -f "$LAST_EVENT_FILE" "$PENDING_FILE"
# Start inotifywait in monitor mode to ensure we don't miss any events while syncing
inotifywait -r -m -e close_write,delete,move "$DATA_DIR" 2>/dev/null | while read -r _; do
date +%s > "$LAST_EVENT_FILE"
if [ ! -f "$PENDING_FILE" ]; then
touch "$PENDING_FILE"
fi
done &
# Background runner that waits for a quiet period before syncing
while true; do
if [ -f "$PENDING_FILE" ]; then
last_time=$(cat "$LAST_EVENT_FILE" 2>/dev/null || echo 0)
now=$(date +%s)
elapsed=$((now - last_time))
if [ "$elapsed" -ge "$DEBOUNCE_SECS" ]; then
rm -f "$PENDING_FILE"
echo "Changes detected in $DATA_DIR, syncing to Google Drive ($REMOTE_PATH)..."
if rclone copy "$DATA_DIR" "$REMOTE_PATH" --config "$CONFIG_PATH" --drive-skip-shortcuts --drive-acknowledge-abuse $SHARED_FLAG; then
echo "File sync successful."
else
echo "File sync failed or partially completed (e.g. active uploads). Will retry..."
# Set last event to now to debounce the next retry
date +%s > "$LAST_EVENT_FILE"
touch "$PENDING_FILE"
fi
fi
fi
sleep 2
done
) &
# Loop B: Sync database /tmp/filebrowser.db to Google Drive when modified (Debounced & Robust)
(
echo "Starting database sync daemon..."
DB_LAST_EVENT="/tmp/db_last_event"
DB_PENDING="/tmp/db_sync_pending"
DEBOUNCE_SECS=3
# Clear any old state
rm -f "$DB_LAST_EVENT" "$DB_PENDING"
# Start inotifywait in monitor mode
inotifywait -m -e modify "$DB_PATH" 2>/dev/null | while read -r _; do
date +%s > "$DB_LAST_EVENT"
if [ ! -f "$DB_PENDING" ]; then
touch "$DB_PENDING"
fi
done &
# Background runner for database sync
while true; do
if [ -f "$DB_PENDING" ]; then
last_time=$(cat "$DB_LAST_EVENT" 2>/dev/null || echo 0)
now=$(date +%s)
elapsed=$((now - last_time))
if [ "$elapsed" -ge "$DEBOUNCE_SECS" ]; then
rm -f "$DB_PENDING"
echo "Database modified, uploading to Google Drive ($REMOTE_PATH)..."
if rclone copyto "$DB_PATH" "$REMOTE_PATH/.filebrowser.db" --config "$CONFIG_PATH" $SHARED_FLAG; then
echo "Database sync successful."
else
echo "Database sync failed. Will retry..."
date +%s > "$DB_LAST_EVENT"
touch "$DB_PENDING"
fi
fi
fi
sleep 1
done
) &
# 4. Start File Browser
echo "Starting File Browser on port 7860..."
filebrowser --port 7860 --address 0.0.0.0 --database "$DB_PATH" --root "$DATA_DIR"