You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

13 KiB

OpenList + Iron Local Deployment SOP

This SOP is for a single-machine deployment where:

  • OpenList runs locally and mounts Aliyun Drive
  • OpenList exposes WebDAV
  • Iron runs locally and uses OpenList WebDAV as a remote backend
  • Iron also keeps its built-in local backend for local reads and recovery

The result is:

Aliyun Drive
  -> OpenList mount
  -> OpenList WebDAV
  -> Iron WebDAV backend
  -> Iron file namespace + policies + replicas

1. What This SOP Assumes

  • You want a practical local deployment first, not a public Internet deployment.
  • OpenList is used as the cloud-drive access layer.
  • Iron is used as the file namespace, replica policy, and repair layer.
  • Aliyun Drive data used by Iron should stay inside a dedicated folder, not the cloud-drive root.

This SOP uses:

  • OpenList on 127.0.0.1:5244
  • Iron on 127.0.0.1:8000
  • Docker for OpenList
  • local Python + uv for Iron

Repository deployment assets used in this SOP:

  • deploy/openlist/docker-compose.yml
  • deploy/openlist/.env.example
  • deploy/iron/iron.env.example
  • deploy/iron/start_iron.sh
  • deploy/systemd/iron.service.example

OpenList also supports manual installation if you prefer not to use Docker.

2. Prerequisites

Prepare these first:

  • Docker
  • Python 3.11+
  • Node.js 20+
  • uv
  • a local checkout of this repository

Recommended local ports:

  • 5244 for OpenList
  • 8000 for Iron

Create a deployment working directory outside the Git repo for runtime data:

mkdir -p ~/iron-deploy/openlist
mkdir -p ~/iron-deploy/iron-data
mkdir -p ~/iron-deploy/iron-temp
mkdir -p ~/iron-deploy/iron-cache

Recommended meaning:

  • ~/iron-deploy/openlist: OpenList runtime data
  • ~/iron-deploy/iron-data: Iron local storage root
  • ~/iron-deploy/iron-temp: Iron upload temp files
  • ~/iron-deploy/iron-cache: Iron remote-read cache

4. Install And Start OpenList

This SOP uses Docker Compose because it is the shortest path to a repeatable local deployment.

Prepare the OpenList env file:

mkdir -p ~/iron-deploy/openlist
cp deploy/openlist/.env.example deploy/openlist/.env

Edit deploy/openlist/.env and set:

  • OPENLIST_BIND_HOST=127.0.0.1
  • OPENLIST_PORT=5244
  • OPENLIST_DATA_DIR=$HOME/iron-deploy/openlist

Start OpenList:

docker compose -f deploy/openlist/docker-compose.yml --env-file deploy/openlist/.env up -d

Check logs:

docker compose -f deploy/openlist/docker-compose.yml logs -f

On first start, OpenList prints the initial admin password in the logs.

Open the admin UI:

http://127.0.0.1:5244

Log in with the OpenList admin account shown on first boot, then immediately change it to a password you control.

5. Create An OpenList User For Iron

Do not let Iron use the OpenList admin account.

In OpenList:

  1. go to Users
  2. create a dedicated user, for example iron
  3. give it a strong password
  4. enable the permissions needed for WebDAV write access

For Iron write access through WebDAV, enable at least:

  • Webdav Read
  • Webdav Manage
  • Make dir or upload
  • Delete
  • Rename
  • Move
  • Copy

Without these, Iron health checks may pass partially but upload or directory creation can fail.

6. Prepare A Dedicated Aliyun Drive Folder

Create a dedicated folder in Aliyun Drive for Iron, for example:

IronGateway

Do not mount the whole cloud-drive root for Iron unless you explicitly want that.

OpenList supports mounting a specific Aliyun folder by Root Folder ID. The OpenList Aliyundrive Open docs describe using root for the drive root, or a folder file_id if you only want a specific folder exposed.

Recommended approach:

  1. create IronGateway in Aliyun Drive
  2. open that folder in the Aliyun Drive Web UI
  3. copy the folder file_id from the URL
  4. use that file_id as the OpenList Root Folder ID

That gives you one isolation layer in OpenList. Later, Iron will also use its own root_path inside that mount, giving you a second isolation layer.

7. Mount Aliyun Drive In OpenList

In OpenList:

  1. go to Storage
  2. click Add Storage
  3. choose driver AliYun Drive (Oauth2) / Aliyundrive Open
  4. set mount path to something stable, for example:
/aliyun-iron
  1. set Root Folder ID to the dedicated Aliyun folder file_id
  2. fill the refresh token from the OpenList Aliyundrive Open authorization flow
  3. save the storage

Important notes from the OpenList docs:

  • normal users can leave Client ID and Secret blank and use the values provided by OpenList
  • the refresh token used here must come from the Aliyundrive Open flow intended for OpenList
  • the docs warn about request rate limiting and advise not to abuse the API

Operational note:

This means the current local-operator path does not require your own Aliyun developer app. That is based on the latest OpenList docs and may change if OpenList or Aliyun changes upstream behavior.

8. Verify OpenList WebDAV Before Touching Iron

OpenList exposes WebDAV at:

http://127.0.0.1:5244/dav/

Before configuring Iron, verify all three things:

  1. the iron OpenList user can log in
  2. the mounted path /aliyun-iron is visible in the OpenList Web UI
  3. the iron user has WebDAV write permissions

The practical target for Iron is:

http://127.0.0.1:5244/dav

Iron will then use root_path to place its own dedicated subtree under the OpenList mount.

9. Install Iron

From the repository root:

UV_CACHE_DIR=.uv-cache uv venv .venv
UV_CACHE_DIR=.uv-cache uv pip install --python .venv/bin/python -e '.[dev]'
npm install
npm run build

Apply database migrations:

./.venv/bin/alembic upgrade head

10. Configure Iron Runtime Environment

Iron reads configuration from environment variables. For repeatable deployment, use the provided env template instead of one-off shell exports.

Create the runtime directories and env file:

mkdir -p ~/iron-deploy/runtime/temp
mkdir -p ~/iron-deploy/runtime/local
mkdir -p ~/iron-deploy/runtime/cache

cp deploy/iron/iron.env.example deploy/iron/iron.env

Edit deploy/iron/iron.env and set:

IRON_DATABASE_URL="sqlite+aiosqlite:////Users/your-user/iron-deploy/iron.db"
IRON_BOOTSTRAP_USERNAME="admin"
IRON_BOOTSTRAP_PASSWORD="replace-this-now"
IRON_SECRET_KEY="replace-with-a-long-random-stable-secret"
IRON_UPLOAD_TEMP_DIR="/Users/your-user/iron-deploy/runtime/temp"
IRON_LOCAL_STORAGE_DIR="/Users/your-user/iron-deploy/runtime/local"
IRON_CACHE_DIR="/Users/your-user/iron-deploy/runtime/cache"
IRON_JOB_POLL_INTERVAL_SECONDS="2"
IRON_JOB_BATCH_SIZE="10"

Important:

  • IRON_SECRET_KEY must be stable after deployment begins, or stored backend passwords become unreadable.
  • the bootstrap user is only auto-created when the database has no users yet
  • changing IRON_BOOTSTRAP_PASSWORD later does not rotate the existing account password

11. Start Iron

Start the service:

./deploy/iron/start_iron.sh

Open:

http://127.0.0.1:8000/app

Log in with:

  • username: IRON_BOOTSTRAP_USERNAME
  • password: IRON_BOOTSTRAP_PASSWORD

Health endpoints:

http://127.0.0.1:8000/api/system/health
http://127.0.0.1:8000/api/system/ready

For a background service on Linux, adapt deploy/systemd/iron.service.example into /etc/systemd/system/iron.service.

12. Confirm The Built-In Local Backend

On first startup, Iron auto-creates the default local backend:

  • name: local-default
  • type: Local Directory
  • policy class: Local

Keep this enabled.

This is the local durable copy that gives you:

  • fast reads
  • local recovery
  • a safe fallback if OpenList or Aliyun is temporarily unavailable

13. Add OpenList As A WebDAV Backend In Iron

In Iron:

  1. open Storage
  2. click Add Backend
  3. choose OpenList / WebDAV
  4. use a stable backend name, for example openlist-aliyun
  5. choose policy class Stable
  6. use read and write priority appropriate for your setup, for example 80

Use config JSON like this:

{
  "endpoint_url": "http://127.0.0.1:5244/dav",
  "username": "iron",
  "password": "your-openlist-iron-password",
  "root_path": "aliyun-iron/iron-data",
  "verify_ssl": false
}

Meaning:

  • endpoint_url: OpenList WebDAV root
  • username / password: the dedicated OpenList user created for Iron
  • root_path: Iron's dedicated subtree
  • verify_ssl: false only because this SOP uses local plain HTTP; use true when you switch to HTTPS

Recommended path layering:

Aliyun folder: IronGateway
OpenList mount path: /aliyun-iron
Iron root_path: aliyun-iron/iron-data

This keeps Iron away from both:

  • the Aliyun drive root
  • the rest of the OpenList namespace

After saving, click Run Check.

Expected result:

  • status becomes Healthy
  • detail points to the configured WebDAV path

14. Configure Replica Policies

Open Policies in Iron and configure at least these defaults:

Recommended first production baseline:

  • Require local replica = on
  • Stable replicas = 1
  • Opportunistic replicas = 0

Interpretation:

  • every file keeps one local copy
  • every file also gets one stable remote copy on OpenList/Aliyun

For each file class (document, image, video, other):

  1. save the policy
  2. confirm the OpenList backend is not excluded
  3. keep the local backend available

Saving a policy automatically enqueues a full reconcile job.

15. First End-To-End Acceptance Test

Use this exact sequence:

  1. in Iron, upload a small text file
  2. open the file detail drawer and check the Storage tab
  3. confirm the desired backend list includes:
    • local backend
    • OpenList WebDAV backend
  4. wait for the replica to become ready, or go to Jobs and run pending jobs
  5. in OpenList, browse the mount path and confirm the file exists under:
/aliyun-iron/iron-data/...
  1. in Aliyun Drive, verify the file appears under the dedicated IronGateway folder

Expected outcome:

  • Iron can upload locally
  • Iron can replicate to OpenList WebDAV
  • OpenList writes into the dedicated Aliyun subtree

After the first manual upload check, run the real acceptance suite:

./.venv/bin/python scripts/real_openlist_suite.py

Useful focused runs:

./.venv/bin/python scripts/real_openlist_acceptance.py
./.venv/bin/python scripts/real_openlist_chaos_acceptance.py
./.venv/bin/python scripts/real_openlist_multi_backend_acceptance.py
./.venv/bin/python scripts/real_openlist_multi_backend_chaos.py

The suite covers:

  • baseline upload, reconcile, download, and direct WebDAV read
  • large-file range reads
  • forced remote recovery after local file deletion
  • OpenList stop/start recovery
  • multi-backend placement, avoidance, re-enable, and replica healing
  • recycle-bin delete and restore with replica validation

Current remote object layout note:

  • Iron stores backend replicas under a structured application object tree such as objects/file/sha256/73/35/<hash>.blob
  • this is intentional application storage layout, not an attempt to disguise replicas as user-authored media files
  • keep Iron inside a dedicated OpenList mount subtree rather than mixing it with personal root folders
  • because the project is still in active development, this layout is treated as the current source of truth rather than a backward-compatible migration target
  • reserved subtrees include objects/preview/..., objects/export/metadata/..., and objects/manifest/... for future generated artifacts and control files

16. What To Check If It Fails

OpenList backend check fails in Iron

Check:

  • OpenList is reachable on 127.0.0.1:5244
  • WebDAV URL is exactly /dav
  • the OpenList iron user password is correct
  • WebDAV permissions include write-related permissions
  • root_path starts with the OpenList mount path, for example aliyun-iron/iron-data

Iron uploads succeed locally but remote replica never appears

Check:

  • Jobs page for failed reconcile or replication jobs
  • OpenList user permissions
  • placement policy excludes or preferred backend settings
  • whether the WebDAV backend is enabled

Files land in the wrong Aliyun location

Check:

  • OpenList Root Folder ID
  • OpenList mount path
  • Iron root_path

Usually this is a path-scoping mistake, not a storage corruption issue.

For a stable local deployment:

  1. keep OpenList and Iron on localhost unless you add a reverse proxy and auth hardening
  2. keep IRON_SECRET_KEY unchanged
  3. back up:
    • iron.db
    • ~/iron-deploy/openlist
    • ~/iron-deploy/runtime/local
    • ~/iron-deploy/runtime/cache
  4. run backend health checks from the Iron Storage page after OpenList upgrades
  5. review the Iron Jobs page when replicas lag or a cloud drive is rate-limited

18. Source References