codeduction/unraid-filen-sync-plugin

★ 0Forks 0PHPGitHub ↗Compare

README

Filen Sync for Unraid

Native Settings plugin for syncing folders between Filen and Unraid. Target: Unraid 6.12+ on x86-64. It uses Filen CLI 0.2.7 and its managed Rclone integration.

Release workflow

Current release: 2026.09.09.9007. Each delivered update gets a new version and a changelog entry. Source edits and builds happen in this folder; you install and test the package on Unraid.

Install on the server

In Plugins → Install Plugin, paste:

https://raw.githubusercontent.com/codeduction/unraid-filen-sync-plugin/main/dist/filen-sync.plg

For an existing installation without an update URL, install version 2026.09.09.9003 once using the URL above or the local commands below. Future versions are then discoverable through Plugins → Check for Updates.

For a local build in the server's plugins share, run in the Unraid terminal:

mkdir -p /boot/config/plugins
cp /mnt/user/plugins/unraid-filen-sync/dist/filen-sync.plg /boot/config/plugins/filen-sync.plg
plugin install /boot/config/plugins/filen-sync.plg

Then open Settings → User Utilities → Filen Sync.

The Dashboard also includes a Filen Sync tile with job counts, active progress and speed, last-success times and jobs needing attention. It refreshes every five seconds while the page is visible and links to Settings. If hidden, enable Filen Sync in the dashboard Content Manager. Authentication saved means an export is present; it does not verify a live Filen connection.

  1. Click Install Filen CLI. The plugin downloads the pinned official Linux binary, checks its SHA-256, verifies that it runs, and caches it on flash for restoration after reboot. The plugin uses its own CLI installation and does not replace another filen command on your server. Alternatively, expand Install from the Unraid terminal and run:

    php /usr/local/emhttp/plugins/filen-sync/worker.php install

    The command prints the installation result. Click Recheck afterwards.

  2. In the Unraid terminal, run /var/local/filen-sync/filen --skip-update export-auth-config. Log in when prompted, including 2FA if enabled. If the exported file is /root/filen-cli-auth-config.txt, click Recheck. The plugin automatically imports it into persistent storage when no authentication is already saved. Normal status polling and worker startup also detect it. Existing plugin authentication takes precedence. To replace an account or use a different export location, paste the file contents into Connect or replace Filen account.

  3. Create a dedicated destination directory inside an existing Unraid share, for example /mnt/user/backups/filen-photos.

  4. Add a job with a Filen path such as /Photos and an existing Unraid folder. Select Filen → Unraid, Unraid → Filen, or Two-way. Existing jobs stay Filen → Unraid until edited.

  5. For a one-way job, choose Copy changes, keep destination extras or Mirror source, delete destination extras, then save. For two-way, choose the initial conflict preference. Click Preview changes, review the counts and file list, then Approve and run. A new or changed job must complete an approved run before its schedule can start.

Plugin commands use Rclone’s --disable-http2 option after an observed HTTP/2 GOAWAY failure during a large scan. HTTPS remains enabled; requests use HTTP/1.1.

Filen automatically downloads and configures managed Rclone on first use. That requires internet access and can take a while before transfer statistics appear.

Publishing updates

The update source is main/dist/filen-sync.plg in codeduction/unraid-filen-sync-plugin.

  1. Update VERSION and add a CHANGELOG.md entry. Versions must sort lexically after all previous releases; the build checks this.
  2. Run python3 build.py and the relevant tests.
  3. Commit source changes and the rebuilt dist/filen-sync.plg, then push to main.

The published package becomes the version Unraid checks. GitHub Actions verifies the committed package matches the source; it does not publish or install releases. Changes pushed without rebuilding the package do not update installed plugins. Use a pull request and wait for checks before merging release changes.

Included

  • CLI detection, installation, reinstall status and checksum verification.
  • Import of Filen's exported authentication config. The saved secret is never returned by the API.
  • Add, edit and delete jobs with direction selection and exclusion patterns. New jobs default to excluding *~ editor backup and undo files; remove the pattern to include them. Existing jobs keep their saved exclusions.
  • Copy or mirror in either direction; two-way sync using Rclone bisync.
  • Manual runs and schedules every 15 minutes, 1 hour, 6 hours or 24 hours.
  • Dry-run previews with counts and file paths, approval before the first run, and cancellation.
  • Enable/disable scheduled runs.
  • Live transferred/total bytes, progress bar, speed, file count, errors, ETA and current filenames when Rclone supplies them.
  • Last completion, last success, recent structured messages and exit status. Running jobs show processing phase, elapsed time, check count and last CLI report. Transfer estimates cover bytes only; metadata and history work may continue afterwards.
  • Array-start check, duplicate-run locks and rejection of overlapping folders on either side.
  • Native Unraid CSRF validation for all API requests.

Jobs run one at a time. A manual run is rejected while another transfer or installation is active. Scheduled jobs wait for a later scheduler tick if the engine is busy. Intervals count from the previous completion, including a failed or cancelled run. Disabling the schedule does not cancel an active transfer.

Direction and deletion behavior

Direction Behavior
Filen → Unraid Filen is the source. Copy keeps local extras; mirror deletes local extras.
Unraid → Filen Unraid is the source. Copy keeps cloud extras; mirror deletes cloud extras.
Two-way Changes and deletions propagate in both directions after initialization.

One-way copy and mirror both overwrite changed destination files. Uploading can create a missing Filen destination folder. The existing Unraid folder must always be available. Deleting a job leaves files on both sides in place.

Preview and approval

The first run starts with Preview changes. While scanning, the page shows activity, elapsed time, changes found and current-pass checks/filenames when Rclone supplies them. There is no overall percentage because the total is unknown and checks can reset between passes. The dry run reports new, modified, deleted, renamed and other operations, with the affected side and file paths. Counts include the full report; the table displays the first 500 changes. Failed or cancelled previews cannot be approved. Comparison details on two-way previews shows listing counts, shared paths and size/timestamp samples for proposed copies. This helps investigate unexpected classifications; it does not verify file contents.

Click Approve and run to start the reviewed job. Previews expire after 15 minutes and become invalid after relevant configuration, account or sync-history changes. A preview is a point-in-time estimate: the actual sync recalculates against current files, so changes made afterwards can affect the result.

New jobs and jobs with changed folders, direction, mode, exclusions or initialization preference wait for a successful approved run before scheduling. Existing schedules from older versions continue until relevant settings change. Once approved, scheduled runs proceed automatically without approval each time. Run now also becomes available: it runs immediately regardless of the schedule interval or whether scheduling is enabled. Preview changes remains available whenever you want to review the next run. Two-way jobs that need reinitialization must be previewed and approved again.

Two-way previews copy history into temporary RAM storage and never update the live baseline. Preview reports disappear after reboot. Previewing a missing upload destination does not create it; an approved transfer can create it.

Two-way initialization and conflicts

Two-way jobs need an approved initial merge before scheduling. Preview changes automatically previews initialization when required. Initialization merges files unique to either side. If a file with the same path differs, your chosen Filen version or Unraid version wins and overwrites the other. The confirmation explains this before the job starts.

Normal runs compare both folders against persistent history, apply additions/edits/deletions in both directions, and preserve simultaneous conflicting edits under renamed files using filen-conflict and unraid-conflict suffixes. Do not treat the initial merge as conflict preservation: initialization uses the selected winner.

An error or interruption pauses the two-way schedule. Changing the account, paired folders, exclusions or sync direction also invalidates the baseline. Review the files and error messages, then initialize again. Reinitialization merges the current contents and can restore files that were deleted from only one side. The plugin never automatically resyncs after an error.

History is stored under /boot/config/plugins/filen-sync/bisync/<job-id>/. Each initialization gets a new history directory; previous directories are retained. This survives reboots but can use significant flash space for very large trees. Rclone's normal bisync checks, including its deletion threshold, remain enabled. During ordinary runs, do not remove both folder contents or edit the same files continuously while a transfer is active.

Storage and first-pass limits

Settings, exported authentication, cached CLI and the final state of each run are stored under /boot/config/plugins/filen-sync/. Live statistics, managed Rclone and worker locks are under /var/local/filen-sync/ in RAM. Progress polling does not write to flash. Final run state is saved once per completion; two-way runs also update persistent baselines. Automatic auth discovery writes a persistent copy once when needed.

The auth config grants account access. Unraid's FAT boot filesystem cannot enforce ordinary Unix file permissions, so protect flash access and backups. Runtime directories are private. Workers run as root; newly downloaded files use permissive share-compatible modes, with SMB access still governed by your share settings. Existing file permissions are not repaired automatically.

This is not a Community Applications listing. Plugin updates are downloaded from the public repository through Unraid’s native plugin updater. The plugin does not install its own updates in the background; unattended installation is controlled by your Unraid plugin auto-update configuration. The Filen CLI version is pinned; managed Rclone is provisioned by Filen. Authentication is validated by the first real transfer, not by saving the config. Paths are entered manually; there is no remote folder browser yet. Statistics may be unavailable while connecting or scanning, and totals can grow during discovery.

Last completed state survives reboot. An unclean reboot can lose information about the most recent in-progress run. Native Settings integration, array lifecycle behavior, SMB access and real authenticated Filen uploads, downloads and bisync still need testing on Unraid.

Remove through Unraid's Plugins page. Removal unregisters the schedule and requests cancellation of active jobs. Saved configuration/authentication and downloaded files are retained for reinstallation.

Development and verification

No frontend build or runtime Python dependency. The plugin uses Unraid's PHP, curl and util-linux setsid. PHP needs proc_open and the POSIX extension.

python3 build.py
/usr/bin/php tests/integration.php
python3 tests/api_test.py
python3 tests/package.py
python3 tests/directions.py  # requires local rclone
python3 tests/previews.py    # requires local rclone
python3 tests/preview_errors.py
python3 tests/ui.py          # requires local chromium
python3 tests/dashboard.py   # requires local chromium
node --check src/app.js
node --test tests/requests.test.cjs
FILEN_TEST_UNRAID_PREPEND=1 python3 tests/api_test.py

integration.php runs the actual worker against a deterministic local CLI double. It checks job storage, transfer arguments, live statistics, success/failure, cancellation of child processes, schedules, destination validation and retained state. api_test.py runs the actual HTTP endpoint and checks page rendering, CSRF, create/edit/delete, mirror confirmation and secret handling. package.py installs and removes the embedded payload in a temporary filesystem and compares every installed file with its source.

The development-only environment variables FILEN_SYNC_DATA, FILEN_SYNC_RUN, FILEN_SYNC_DEST_ROOT, FILEN_SYNC_VAR_FILE and FILEN_SYNC_AUTH_EXPORT isolate test storage and substitute an Unraid share/CSRF fixture. The tests/ directory is not packaged.

See VERIFICATION.md for the checks performed on this first pass.

References

Contributors

codeduction

Issues